package com.authine.cloudpivot.engine.api.facade.dubbo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.aliyun.oss.common.comm.ServiceClient;
import com.authine.cloudpivot.engine.api.constants.ModelConstant;
import com.authine.cloudpivot.engine.api.exceptions.ServiceException;
import com.authine.cloudpivot.engine.api.facade.*;
import com.authine.cloudpivot.engine.api.model.bizform.BizFormCommentModel;
import com.authine.cloudpivot.engine.api.model.bizform.BizFormModel;
import com.authine.cloudpivot.engine.api.model.bizmodel.*;
import com.authine.cloudpivot.engine.api.model.bizquery.*;
import com.authine.cloudpivot.engine.api.model.importData.FileOperationResult;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.*;
import com.authine.cloudpivot.engine.api.model.runtime.ModelViewType;
import com.authine.cloudpivot.engine.api.model.system.PairSettingModel;
import com.authine.cloudpivot.engine.api.utils.ModelUtil;
import com.authine.cloudpivot.engine.component.query.api.*;
import com.authine.cloudpivot.engine.component.query.api.helper.*;
import com.authine.cloudpivot.engine.domain.bizform.BizForm;
import com.authine.cloudpivot.engine.domain.bizform.BizFormComment;
import com.authine.cloudpivot.engine.domain.bizform.BizFormCommentAttachment;
import com.authine.cloudpivot.engine.domain.bizmodel.BizDataRule;
import com.authine.cloudpivot.engine.domain.bizmodel.BizMethodMapping;
import com.authine.cloudpivot.engine.domain.bizmodel.BizProperty;
import com.authine.cloudpivot.engine.domain.bizmodel.BizSchema;
import com.authine.cloudpivot.engine.domain.bizquery.*;
import com.authine.cloudpivot.engine.domain.runtime.*;
import com.authine.cloudpivot.engine.domain.system.PairSetting;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.status.DataRowStatus;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.engine.enums.status.UserStatus;
import com.authine.cloudpivot.engine.enums.status.WorkflowInstanceStatus;
import com.authine.cloudpivot.engine.enums.type.*;
import com.authine.cloudpivot.engine.enums.type.bizmodel.QueryLevelType;
import com.authine.cloudpivot.engine.service.bizform.BizFormCommentService;
import com.authine.cloudpivot.engine.service.bizform.BizFormJsonResolveService;
import com.authine.cloudpivot.engine.service.bizform.BizFormService;
import com.authine.cloudpivot.engine.service.bizmodel.BizPropertyService;
import com.authine.cloudpivot.engine.service.bizmodel.BizSchemaService;
import com.authine.cloudpivot.engine.service.bizquery.*;
import com.authine.cloudpivot.engine.service.bizrule.CalculateRuleService;
import com.authine.cloudpivot.engine.service.runtime.*;
import com.authine.cloudpivot.engine.service.system.PairSettingService;
import com.authine.cloudpivot.engine.service.system.SequenceSettingService;
import com.authine.cloudpivot.engine.service.util.BizFormUtil;
import com.authine.cloudpivot.engine.utils.ThreadLocalAttributes;
import com.authine.cloudpivot.foundation.orm.api.Db;
import com.authine.cloudpivot.foundation.orm.api.model.*;
import com.authine.cloudpivot.foundation.util.api.PropertyValidateHelper;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import sun.misc.Request;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author longhai
 */
@Service
@Transactional
@Slf4j
public class BizObjectFacadeImpl implements BizObjectFacade {

    ThreadPoolExecutor batchInsertPool = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new DefaultThreadFactory("batchInsertPool"));
    ThreadPoolExecutor checkRelativePool = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new DefaultThreadFactory("checkRelativePool"));
    /**
     * 批量插入数据库批次大小
     */
    private static final int BATCH_INSERT_SIZE = 2000;

    @Autowired
    private BizObjectLocalCacheService bizObjectLocalCacheService;

    @Autowired
    private BizObjectService bizObjectService;

    @Autowired
    private BizQueryColumnService bizQueryColumnService;

    @Autowired
    private BizQueryConditionService bizQueryConditionService;

    @Autowired
    private BizQuerySortService bizQuerySortService;

    @Autowired
    private BizQueryService bizQueryService;

    @Autowired
    private BizQueryPresentService bizQueryPresentService;

    @Autowired
    private DepartmentFacade departmentFacade;

    @Autowired
    private UserFacade userFacade;

    @Autowired
    private Db db;

    @Autowired
    private BizSchemaService bizSchemaService;

    @Autowired
    private BizPropertyService bizPropertyService;

    @Autowired
    private SequenceSettingService sequenceSettingService;

    @Autowired
    private BizFormService bizFormService;

    @Autowired
    private WorkflowInstanceFacade bizWorkflowInstanceService;

    @Autowired
    private BizWorkitemFacade bizWorkitemService;

    @Autowired
    private BizWorkitemFinishedFacade bizWorkitemFinishedService;

    @Autowired
    private BizObjectConverter bizObjectConverter;

    @Autowired
    private PairSettingService pairSettingService;

    @Autowired
    private BizFormCommentService bizFormCommentService;

    @Autowired
    private CalculateRuleService calculateRuleService;

    @Autowired
    private BizObjectBatchUpdateRecordService batchUpdateRecordService;

    @Autowired
    private BizQueryFacade bizQueryFacade;

    @Autowired
    private BizFormFacade bizFormFacade;

    @Autowired
    private BizSchemaFacade bizSchemaFacade;

    @Autowired
    private PermissionManagementFacade permissionManagementFacade;

    @Autowired
    private OrganizationFacade organizationFacade;

    @Autowired
    private BizFormJsonResolveService bizFormJsonResolveService;

    private Map<String, DepartmentModel> userDepartmentMap = new HashMap<>();

    static String getIdFromObject(Object m) {
        if (m == null) {
            return null;
        }
        if (m instanceof String) {
            final String s = ((String) m).trim();
            if (s.startsWith("{")) {
                return JSON.parseObject(s, SelectionValue.class).getId();
            }
            if (s.startsWith("[")) {
                return JSON.parseObject(s, new TypeReference<List<SelectionValue>>() {
                        })
                        .stream()
                        .map(SelectionValue::getId)
                        .findFirst()
                        .orElse(null);
            } else {
                return s;
            }
        }
        if (m instanceof SelectionValue) {
            return ((SelectionValue) m).getId();
        }
        if (m instanceof Map) {
            return (String) ((Map) m).get("id");
        }

        if (isIterable(m)) {
            List list = asList(m);
            Object o = list.stream().findFirst().orElse(null);
            return getIdFromObject(o);
        }
        throw new RuntimeException("不支持的从:" + m + "获取id值");
    }

    public static boolean isIterable(@Nullable Object value) {
        if (value == null) {
            return false;
        }
        if (value instanceof Iterable) {
            return true;
        }
        if (value instanceof Iterator) {
            return true;
        }

        return value.getClass().isArray();
    }

    public static List asList(@Nullable Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof List) {
            return (List) value;
        }
        if (value instanceof Iterable) {
            return Lists.newArrayList((Iterable) value);
        }
        if (value instanceof Iterator) {
            return Lists.newArrayList((Iterator) value);
        }

        if (value.getClass().isArray()) {
            if (!value.getClass().getComponentType().isPrimitive()) {
                return Arrays.asList((Object[]) value);
            } else {
                int size = Array.getLength(value);
                Object[] objects = new Object[size];
                for (int i = 0; i < size; i++) {
                    objects[i] = Array.get(value, i);
                }
                return Arrays.asList(objects);
            }
        }

        return Collections.singletonList(value);
    }

    private UserModel getUser(String userId) {
        UserModel user = userFacade.get(userId);
        if (user == null) {
            log.debug("用户不存在, userId ={}.", userId);
            throw new ServiceException(ErrCode.ORG_USER_NONEXISTENT);
        }
        return user;
    }

    private DepartmentModel getDepartmentByUserId(String userId) {
        DepartmentModel department = null;
        UserModel user = userFacade.get(userId);
        if (user != null && !StringUtils.isEmpty(user.getDepartmentId())) {
            department = departmentFacade.get(user.getDepartmentId());
        }

        if (department == null) {
            List<DepartmentModel> departmentList = departmentFacade.listByUserId(userId);
            if (CollectionUtils.isNotEmpty(departmentList)) {
                department = departmentList.get(0);
            }
        }
        return department;
    }

    @Override
    public BizObjectCreatedModel getBizObject(final String userId, final String schemaCode, final String objectId) {
        return getBizObject(userId, schemaCode, objectId, null);
    }

    @Override
    public BizObjectCreatedModel getBizObjectWithoutChild(String userId, String schemaCode, String objectId) {
        return getBizObject(userId, schemaCode, objectId, BizObjectOptions.builder().notQueryChild().build());
    }

    @Override
    public BizObjectCreatedModel getBizObject(final String userId, final String schemaCode, final String objectId, BizObjectOptions options) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(schemaCode)) {
            log.debug("用户Id或schemaCode为空.");
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }

        if (bizSchemaService.getBySchemaCode(schemaCode) == null) {
            throw new ServiceException(ErrCode.BIZ_SCHEMA_MODEL_NOT_EXIST, schemaCode);
        }

        //new bizobject
        if (StringUtils.isEmpty(objectId)) {
            UserModel user = getUser(userId);
            DepartmentModel department = departmentFacade.get(user.getDepartmentId());
            String departmentName = department == null ? null : department.getName();

            Map<String, Object> data = Maps.newHashMap();
            if (user != null) {
                SelectionValue userSelectionValue = new SelectionValue();
                userSelectionValue.setId(user.getId());
                userSelectionValue.setType(UnitType.USER);
                userSelectionValue.setName(user.getName());
                data.put(DefaultPropertyType.CREATER.getCode(), Lists.newArrayList(userSelectionValue));
            }
            if (department != null) {
                SelectionValue deptSelectionValue = new SelectionValue();
                deptSelectionValue.setId(department.getId());
                deptSelectionValue.setType(UnitType.DEPARTMENT);
                deptSelectionValue.setName(department.getName());
                data.put(DefaultPropertyType.CREATED_DEPT_ID.getCode(), Lists.newArrayList(deptSelectionValue));
            }

            BizObjectCreatedModel bizObject = new BizObjectCreatedModel(schemaCode, data, false);
            String newId = bizObjectService.genBizObjectId();
            log.debug("返回一个新对象， objectId={}.", newId);
            bizObject.setId(newId);
//            bizObject.setCreater(user.getName());
//            bizObject.setCreatedDeptId(departmentName);
            return bizObject;
        }
        // from db
        BizObject object = null;
        try {
            ThreadLocalAttributes.setThreadAttribute("currentUserId", userId);
            object = getBizObjectWithOptions(schemaCode, objectId, options);
        } catch (Exception e) {
            throw e;
        } finally {
            ThreadLocalAttributes.removeThreadAttribute("currentUserId");
        }
        return new BizObjectCreatedModel(schemaCode, object.getData(), object.isLoadedFromDb());
    }

    @Override
    public BizObjectCreatedModel getBizObject(String schemaCode, String objectId) {
        return getBizObjectModelWithOptions(schemaCode, objectId, null);
    }

    @Override
    public BizObjectCreatedModel getBizObjectWithoutChild(String schemaCode, String objectId) {
        return getBizObjectModelWithOptions(schemaCode, objectId, BizObjectOptions.builder().notQueryChild().build());
    }

    private BizObject getBizObjectWithOptions(String schemaCode, String objectId, BizObjectOptions options) {
        return bizObjectService.loadBizObject(schemaCode, objectId, null, options);
    }

    private BizObjectCreatedModel getBizObjectModelWithOptions(String schemaCode, String objectId, BizObjectOptions options) {
        BizObject bizObject = getBizObjectWithOptions(schemaCode, objectId, options);
        return new BizObjectCreatedModel(schemaCode, bizObject.getData(), bizObject.isLoadedFromDb());
    }


    @Override
    public boolean existsBizObject(String schemaCode, String objectId) {
        return bizObjectService.existsBizObject(schemaCode, objectId);
    }

    @Override
    public String saveBizObject(final String userId, final BizObjectModel bizObject, Boolean syncInstance) {
        return saveBizObject(userId, bizObject, syncInstance, null);
    }

    @Override
    public String saveBizObject(final String userId, final BizObjectModel bizObject, Boolean syncInstance, BizObjectOptions options) {
        if (bizObject == null) {
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }

        //当更新了拥有者后，把拥有者部门也修改
        if (Objects.nonNull(bizObject.getData())) {
            Object owner = bizObject.getData().get("owner");
            if (Objects.nonNull(owner)) {
                Object boOwner = bizObject.getObject(DefaultPropertyType.OWNER.getCode());
                String ownerId = this.getSelectionId(boOwner, DefaultPropertyType.OWNER.getCode());

                String objectId = bizObject.getId();
                if (StringUtils.isEmpty(objectId)) {
                    modifyOwnerInfo(ownerId, bizObject);
                } else {
                    BizObjectCreatedModel oldObj = getBizObject(bizObject.getSchemaCode(), objectId);
                    if (isModifyOwner(ownerId, oldObj)) {
                        modifyOwnerInfo(ownerId, bizObject);
                    }
                }
            }
        }

        updateChildTableModifyProperties(userId, bizObject);

        //long start = System.currentTimeMillis();

        if (StringUtils.isEmpty(bizObject.getFormCode())) {
            List<BizForm> bizForms = bizFormService.getListBySchemaCode(bizObject.getSchemaCode());
            if (CollectionUtils.isNotEmpty(bizForms)) {
                bizObject.setFormCode(bizForms.get(0).getCode());
            }
        }

        //校验单行文本是否重复 add by lijianglong  2019-11-8 beginnames的数据
        log.debug("------开始校验单行文本是否重复------");
        bizFormService.verifyControlProperty(bizObject);
        log.debug("------校验单行文本结束------");
        //校验单行文本是否重复 add by lijianglong  2019-11-8 end

        //log.info("setFormCode cost : {}", System.currentTimeMillis() - start);

        if (log.isTraceEnabled()) {
            log.trace("bizObject json = {}", JSONObject.toJSONString(bizObject));
        }
        final BizSchema bizSchema = bizSchemaService.getBySchemaCode(bizObject.getSchemaCode());
        if (bizSchema == null) {
            log.debug("数据模型为空，schemaCode = {}", bizObject.getSchemaCode());
            throw new ServiceException(ErrCode.BIZ_SCHEMA_MODEL_NOT_EXIST, bizObject.getSchemaCode());
        }
        if (log.isDebugEnabled()) {
            log.debug("summary = {}", bizSchema.getSummary());
        }

        //log.info("getBySchemaCode cost : {}", System.currentTimeMillis() - start);

        if (StringUtils.isEmpty(bizObject.getId())) {
            log.debug("objectId is null...");
            return createBizObject(userId, bizSchema, bizObject);

        } else {
            Optional<BizObject> load = bizObjectLocalCacheService.load(bizObject.getSchemaCode(), bizObject.getId());

            if (!load.isPresent()) {
                log.debug("bizObject do not from db...");
                return createBizObject(userId, bizSchema, bizObject);
            } else {
                log.debug("bizObject from db...");
                return updateBizObject(userId, bizSchema, bizObject, load.get(), syncInstance, options);
            }
        }
    }

    private boolean isModifyOwner(String ownerId, BizObjectCreatedModel oldObj) {
        if (Objects.isNull(oldObj)) {
            return false;
        }
        String oldOwnerId = this.getSelectionId(oldObj.getOwner(), DefaultPropertyType.OWNER.getCode());
        if (StringUtils.isEmpty(oldOwnerId)) {
            return false;
        }
        return !org.apache.commons.lang3.StringUtils.equals(ownerId, oldOwnerId);
    }

    private void modifyOwnerInfo(String ownerId, BizObjectModel bizObject) {
        UserModel userById = userFacade.get(ownerId);
        String ownerDepartmentId = userById.getDepartmentId();
        bizObject.setOwnerDeptId(ownerDepartmentId);
    }

    /**
     * 更新子表修改人和修改时间字段
     *
     * @param userId
     * @param bizObject
     */
    private void updateChildTableModifyProperties(String userId, BizObjectModel bizObject) {
        for (Map.Entry<String, Object> entry : bizObject.getData().entrySet()) {
            BizProperty bizProperty = bizPropertyService.get(bizObject.getSchemaCode(), entry.getKey());

            if (Objects.isNull(bizProperty)) {
                continue;
            }

            if (bizProperty.getPropertyType() != BizPropertyType.CHILD_TABLE) {
                continue;
            }

            List<BizProperty> bizProperties = bizPropertyService.getListBySchemaCode(entry.getKey(), true);

            List<Map<String, Object>> childTableList = (ArrayList) entry.getValue();
            if (CollectionUtils.isEmpty(childTableList)) {
                continue;
            }

            boolean exists = bizProperties.stream().anyMatch(property -> DefaultSubPropertyType.MODIFIED_TIME.getCode().equals(property.getCode()));

            //判断当前子表是否存在修改时间字段，如果有才进行数据填充，用于兼容历史版本
            if (exists) {
                for (Map<String, Object> valueMap : childTableList) {
                    valueMap.put(DefaultSubPropertyType.MODIFIED_TIME.getCode(), new Date());
                    valueMap.put(DefaultSubPropertyType.MODIFIER.getCode(), userId);
                }
            }
        }
    }

    /**
     * 列表导入校验表单是否关联流程实例
     *
     * @param bizObject
     * @param queryField
     * @return
     */
    @Override
    public Boolean checkBindWorkFlowInstance(final String userId, final BizObjectModel bizObject, final String queryField) {
        if (bizObject == null) {
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }
        String schemaCode = bizObject.getSchemaCode();
        if (StringUtils.isEmpty(bizObject.getFormCode())) {
            List<BizForm> bizForms = bizFormService.getListBySchemaCode(schemaCode);
            if (CollectionUtils.isNotEmpty(bizForms)) {
                bizObject.setFormCode(bizForms.get(0).getCode());
            }
        }
        final BizSchema bizSchema = bizSchemaService.getBySchemaCode(schemaCode);
        if (bizSchema == null) {
            log.debug("数据模型为空，schemaCode = {}", schemaCode);
            throw new ServiceException(ErrCode.BIZ_SCHEMA_CODE_INVALID);
        }
        //queryField为空，则是新增
        if (StringUtils.isEmpty(queryField)) {
            log.debug("queryField is null...");
            return Boolean.FALSE;
        }
        //系统数据项---单据号
        if (queryField.equals(DefaultPropertyType.SEQUENCE_NO.getCode())) {
            String sequenceNo = bizObject.getSequenceNo();
            if (!StringUtils.isEmpty(sequenceNo)) {
                List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCodeFromDB(schemaCode);
                if (CollectionUtils.isNotEmpty(bizQuerys)) {
                    String code = bizQuerys.get(0).getCode();
                    //若选择单据号，则会根据所传单据号对已有数据做更新
                    if (!StringUtils.isEmpty(code)) {
                        //处理id查询条件信息
                        List<FilterExpression> filterExprCodes = new ArrayList<>();
                        FilterExpression filterExprCode = FilterExpression.empty;
                        //获取数据查询条件
                        filterExprCodes.add(Q.it("sequenceNo", FilterExpression.Op.Eq, bizObject.getSequenceNo()));
                        filterExprCode = filterExprCodes.get(0);
                        BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
                        bizObjectQueryModel.setFilterExpr(filterExprCode);
                        bizObjectQueryModel.setSchemaCode(schemaCode);
                        //分页信息
                        int page = 0;
                        int size = Integer.MAX_VALUE;
                        PageableImpl pageable = new PageableImpl(page * size, size);
                        bizObjectQueryModel.setPageable(pageable);
                        bizObjectQueryModel.setQueryCode(code);

                        Page<BizObjectModel> bizObjectModelPage = queryBizObjects(bizObjectQueryModel);
                        List<? extends BizObjectModel> content = bizObjectModelPage.getContent();

                        if (!CollectionUtils.isEmpty(content)) {
                            BizObjectModel bizObjectModel = content.get(0);
                            String bizObjectModelId = bizObjectModel.getId();
                            BizObjectCreatedModel bizObjectDb = getBizObject(userId, schemaCode, bizObjectModelId);
                            String sequenceNoDb = bizObjectDb.getSequenceNo();
                            if (sequenceNo.equals(sequenceNoDb)) {
                                String bizObjectId = bizObjectModel.getId();
                                return isFormBindWorkflowInstance(bizObjectId);
                            }
                        }
                    }
                }
            }
        }
        //系统数据项---数据标题
        if (queryField.equals(DefaultPropertyType.NAME.getCode())) {
            String name = bizObject.getName();
            //若选择数据标题，则会根据所传数据标题对已有数据做更新
            if (!StringUtils.isEmpty(name)) {
                List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCode(schemaCode);
                if (CollectionUtils.isNotEmpty(bizQuerys)) {
                    String code = bizQuerys.get(0).getCode();
                    if (!StringUtils.isEmpty(code)) {
                        List<FilterExpression> filterExprNames = new ArrayList<>();
                        FilterExpression filterExprName = FilterExpression.empty;
                        //获取数据查询条件
                        filterExprNames.add(Q.it("name", FilterExpression.Op.Eq, bizObject.getName()));
                        filterExprName = filterExprNames.get(0);
                        BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
                        bizObjectQueryModel.setFilterExpr(filterExprName);
                        bizObjectQueryModel.setSchemaCode(schemaCode);
                        //分页信息
                        int page = 0;
                        int size = Integer.MAX_VALUE;
                        PageableImpl pageable = new PageableImpl(page * size, size);
                        bizObjectQueryModel.setPageable(pageable);
                        bizObjectQueryModel.setQueryCode(code);

                        Page<BizObjectModel> bizObjectModelPage = queryBizObjects(bizObjectQueryModel);
                        List<? extends BizObjectModel> content = bizObjectModelPage.getContent();

                        if (!CollectionUtils.isEmpty(content)) {
                            BizObjectModel bizObjectModel = content.get(0);
                            String bizObjectId = bizObjectModel.getId();
                            log.info("bizObjectId的数据：bizObjectId={}", JSONObject.toJSONString(bizObjectId));
                            BizObjectCreatedModel bizObjectDb = getBizObject(userId, schemaCode, bizObjectId);
                            String nameDb = bizObjectDb.getName();
                            if (name.equals(nameDb)) {
                                String bizObjectIdDb = bizObjectModel.getId();
                                return isFormBindWorkflowInstance(bizObjectIdDb);
                            }
                        }
                    }
                }
            }
        }
        //已发布短文本数据项
        List<BizProperty> properties = bizPropertyService.getListBySchemaCode(schemaCode, true);
        if (CollectionUtils.isEmpty(properties)) {
            return Boolean.FALSE;
        }
        for (BizProperty bizPropertyMode : properties) {
            if (bizPropertyMode.getPropertyType() != BizPropertyType.SHORT_TEXT) {
                continue;
            }
            Boolean published = bizPropertyMode.getPublished();
            if (published == null || !published) {
                continue;
            }
            if (!queryField.equals(bizPropertyMode.getCode())) {
                continue;
            }
            Object propertyValue = bizObject.getData().get(bizPropertyMode.getCode());
            if (propertyValue != null && StringUtils.isNotBlank(propertyValue.toString())) {
                List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCode(schemaCode);
                if (CollectionUtils.isEmpty(bizQuerys)) {
                    continue;
                }
                String code = bizQuerys.get(0).getCode();
                if (StringUtils.isEmpty(code)) {
                    continue;
                }

                //获取数据查询条件
                FilterExpression filterExprValue = Q.it(queryField, FilterExpression.Op.Eq, propertyValue);

                if (log.isDebugEnabled()) {
                    log.debug("===333====已发布短文本数据项 filterExprValue==============={}", JSONObject.toJSONString(filterExprValue));
                }
                BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
                bizObjectQueryModel.setFilterExpr(filterExprValue);
                //分页信息
                PageableImpl pageable = new PageableImpl(0, Integer.MAX_VALUE);
                bizObjectQueryModel.setPageable(pageable);
                bizObjectQueryModel.setSchemaCode(schemaCode);
                bizObjectQueryModel.setQueryCode(code);
                Page<BizObjectModel> bizObjectModelPage = queryBizObjects(bizObjectQueryModel);
                List<? extends BizObjectModel> content = bizObjectModelPage.getContent();
                if (!CollectionUtils.isEmpty(content)) {
                    for (BizObjectModel bizObjectModel : content) {
                        String bizObjectModelId = bizObjectModel.getId();
                        log.info("bizObjectModelId的数据：bizObjectModelId={}", JSONObject.toJSONString(bizObjectModelId));
                        BizObjectCreatedModel bizObjectDb = getBizObject(userId, schemaCode, bizObjectModelId);
                        Object propertyDb = bizObjectDb.getData().get(bizPropertyMode.getCode());
                        if (propertyValue.equals(propertyDb)) {
                            String bizObjectId = bizObjectModel.getId();
                            return isFormBindWorkflowInstance(bizObjectId);
                        }
                    }
                }
            }
        }
        return Boolean.FALSE;
    }

    @Override
    public String saveBizObjectModel(final String userId, final BizObjectModel bizObject, final String queryField) {
        if (bizObject == null) {
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }
        String schemaCode = bizObject.getSchemaCode();
        if (StringUtils.isEmpty(bizObject.getFormCode())) {
            List<BizForm> bizForms = bizFormService.getListBySchemaCode(schemaCode);
            if (CollectionUtils.isNotEmpty(bizForms)) {
                bizObject.setFormCode(bizForms.get(0).getCode());
            }
        }
        if (log.isTraceEnabled()) {
            log.trace("bizObject json = {}", JSONObject.toJSONString(bizObject));
        }
        final BizSchema bizSchema = bizSchemaService.getBySchemaCode(schemaCode);
        if (bizSchema == null) {
            log.debug("数据模型为空，schemaCode = {}", schemaCode);
            throw new ServiceException(ErrCode.BIZ_SCHEMA_CODE_INVALID);
        }
        if (log.isDebugEnabled()) {
            log.debug("summary = {}", bizSchema.getSummary());
        }
        log.info("查询参数：queryField={}", JSONObject.toJSONString(queryField));
        if (StringUtils.isEmpty(queryField)) {
            log.debug("queryField is null...");
            return createBizObject(userId, bizSchema, bizObject);
        } else {
            switch (queryField) {
                //系统数据项---单据号
                case "sequenceNo":
                    return ProcessingSequenceNo(userId, bizObject, schemaCode, bizSchema);
                //系统数据项---数据标题
                case "name":
                    return ProcessingName(userId, bizObject, schemaCode, bizSchema);
            }
            //已发布短文本数据项
            return ProcessingShortText(userId, bizObject, schemaCode, bizSchema, queryField);
        }

    }

    @Override
    public void batchSaveBizObjectModel(String userId, List<BizObjectModel> bizObjectModelList, String queryFiled) {
        if (CollectionUtils.isEmpty(bizObjectModelList)) {
            return;
        }
        // 构建一个模板模型，生成共同属性，不用每次重复生成
        BizObjectModel defaultTemplateModel = bizObjectModelList.get(0);
        String schemaCode = defaultTemplateModel.getSchemaCode();
        if (StringUtils.isEmpty(defaultTemplateModel.getFormCode())) {
            List<BizForm> bizForms = bizFormService.getListBySchemaCode(schemaCode);
            if (CollectionUtils.isNotEmpty(bizForms)) {
                defaultTemplateModel.setFormCode(bizForms.get(0).getCode());
            }
        }
        List<BizDataRule> calculateRuleList = new ArrayList<>();
        //主表计算规则
//        List<BizDataRule> calculateRuleListMain = bizDataRuleService.getListBySchemaCodeAndDataRuleType(schemaCode, DataRuleType.CALCULATE_RULE);
//        calculateRuleList.addAll(calculateRuleListMain);
//        List<String> schemaCodeList = new ArrayList<>();
//        schemaCodeList.add(schemaCode);
//        List<BizProperty> bizPropertyList = bizPropertyService.findBySchemaCodeIn(schemaCodeList,true);
//        bizPropertyList = bizPropertyList.stream().filter(f->f.getPropertyType().equals(BizPropertyType.CHILD_TABLE)).collect(Collectors.toList());
//        for (BizProperty b:bizPropertyList) {
//            //子表计算规则
//            List<BizDataRule> calculateRuleListChild = bizDataRuleService.getListBySchemaCodeAndDataRuleType(b.getCode(), DataRuleType.CALCULATE_RULE);
//            calculateRuleList.addAll(calculateRuleListChild);
//        }
        BizSchema bizSchema = bizSchemaService.getBySchemaCode(schemaCode);
        String boCreate = defaultTemplateModel.getString(DefaultPropertyType.CREATER.getCode());
        String createBy = StringUtils.isEmpty(boCreate) ? userId : boCreate;
        defaultTemplateModel.setCreater(createBy);
        String sequenceStatus = defaultTemplateModel.getString(DefaultPropertyType.SEQUENCE_STATUS.getCode());
        if (StringUtils.isEmpty(sequenceStatus)) {
            defaultTemplateModel.setSequenceStatus(WorkflowInstanceStatus.PROCESSING.toString());
        }
        DepartmentModel department = getDepartmentByUserId(createBy);
        if (department != null) {
            defaultTemplateModel.setCreatedDeptId(department.getId());
        }
        defaultTemplateModel.setModifier(userId);
        defaultTemplateModel.setCreatedTime(parseData(new Date()));
        defaultTemplateModel.setModifiedTime(new Date());
        //预先批量生成单据号
        sequenceSettingService.batchGenerateSequenceNo(bizSchema.getCode(), defaultTemplateModel.getFormCode(), bizObjectModelList.size());
        Map<String, List<Map<String, Object>>> queryFiledMap = genQueryFiledMap(schemaCode, queryFiled);
        List<List<BizObjectModel>> partition = ListUtils.partition(bizObjectModelList, BATCH_INSERT_SIZE);
        AtomicInteger index = new AtomicInteger();
        CountDownLatch countDownLatch = new CountDownLatch(partition.size());
        partition.forEach(item -> batchInsertPool.execute(() -> {
            try {
                List<BizObject> bizObjectInsertList = new ArrayList<>(item.size());
                long begin = System.currentTimeMillis();
                item.forEach(bizObjectModel -> {
                    if (MapUtils.isNotEmpty(queryFiledMap) && queryFiledMap.containsKey(String.valueOf(bizObjectModel.getData().get(queryFiled)))) {
                        List<Map<String, Object>> dataDbList = queryFiledMap.get(String.valueOf((bizObjectModel.get(queryFiled))));
                        dataDbList.forEach(dataDb -> {
                            BizObject bizObject = buildBizObject(userId, bizObjectModel, defaultTemplateModel, bizSchema, calculateRuleList, dataDb);
                            bizObjectLocalCacheService.update(bizObject);
                        });
                    } else {
                        bizObjectInsertList.add(buildBizObject(userId, bizObjectModel, defaultTemplateModel, bizSchema, calculateRuleList, null));
                    }
                });
                long end = System.currentTimeMillis();
                log.info("batch{}, buildData ,size:{}, time:{}", index.get(), item.size(), end - begin);
                begin = end;
                bizObjectLocalCacheService.batchInsertObject(bizObjectInsertList, "insert");
                end = System.currentTimeMillis();
                log.info("batch{} batchInsert,size:{}, time:{}", index.get(), item.size(), end - begin);
            } catch (Exception e) {
                log.error("数据插入失败,", e);
            } finally {
                countDownLatch.countDown();
            }
        }));
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<BizObjectModel> modifiedBizObjects(String userId, List<BizObjectModel> bizObjects, BizSchemaModel bizSchemaModel) {
        return BizObjectFacade.super.modifiedBizObjects(userId, bizObjects, bizSchemaModel);
    }

    @Override
    public List<BizObjectModel> asyncModifyBizObjects(String userId, List<BizObjectModel> bizObjects, BizSchemaModel bizSchemaModel) {
        return BizObjectFacade.super.asyncModifyBizObjects(userId, bizObjects, bizSchemaModel);
    }

    private Map<String, List<Map<String, Object>>> genQueryFiledMap(String schemaCode, String queryFiled) {
        if (StringUtils.isBlank(queryFiled) || "false".equals(queryFiled)) {
            return null;
        }
        Page<Map<String, Object>> page = bizObjectService.queryBizObjects(new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {

                return Q.it(queryFiled, FilterExpression.Op.IsNotNull, "");
            }

            @Override
            public List<String> getDisplayFields() {
                HashSet<String> displayFields = Sets.newHashSet(DefaultPropertyType.ID.getCode(), queryFiled, DefaultPropertyType.NAME.getCode(), DefaultPropertyType.SEQUENCE_NO.getCode(), DefaultPropertyType.CREATED_TIME.getCode());
                return new ArrayList<>(displayFields);
            }

            @Override
            public Pageable getPageable() {
                return new PageableImpl(0, Integer.MAX_VALUE);
            }
        });
        if (page == null || CollectionUtils.isEmpty(page.getContent())) {
            return null;
        }
        List<Map<String, Object>> content = (List<Map<String, Object>>) page.getContent();
        Map<String, List<Map<String, Object>>> result = Maps.newHashMapWithExpectedSize(content.size());
        content.forEach(item -> {
            String key = String.valueOf(item.get(queryFiled));
            String id = String.valueOf(item.get(DefaultPropertyType.ID.getCode()));

            List<Map<String, Object>> list = result.get(key);
            if (list == null) {
                list = new ArrayList<>();
                result.put(key, list);
            }
            list.add(item);
        });
        return result;
    }


    private BizObject buildBizObject(String userId, BizObjectModel bizObjectModel, BizObjectModel defaultTemplateModel, BizSchema bizSchema, List<BizDataRule> calculateRuleList, Map<String, Object> dataDb) {
        if (bizObjectModel == null) {
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }
        bizObjectModel.setFormCode(defaultTemplateModel.getFormCode());
        String creater = defaultTemplateModel.getData().get(DefaultPropertyType.CREATER.getCode()).toString();
        bizObjectModel.setCreater(creater);
        String owner = bizObjectModel.getString(DefaultPropertyType.OWNER.getCode());
        if (StringUtils.isEmpty(owner)) {
            owner = userId;
            bizObjectModel.setOwner(owner);
        }
        String sequenceStatus = defaultTemplateModel.getSequenceStatus();
        bizObjectModel.setSequenceStatus(sequenceStatus);
        DepartmentModel department = getDepartmentInUserMap(creater);
        if (department != null) {
            bizObjectModel.setCreatedDeptId(department.getId());
        }
        //设置所属人部门
        String ownerId = getIdFromObject(bizObjectModel.get(DefaultPropertyType.OWNER.getCode()));
        if (!creater.equals(ownerId)) {
            DepartmentModel ownerDepartment = getDepartmentInUserMap(ownerId);
            if (ownerDepartment != null) {
                bizObjectModel.setOwnerDeptId(ownerDepartment.getId());
                bizObjectModel.setOwnerDeptQueryCode(ownerDepartment.getQueryCode());
            }
        } else if (department != null) {
            bizObjectModel.setOwnerDeptId(department.getId());
            bizObjectModel.setOwnerDeptQueryCode(department.getQueryCode());
        }

        if (dataDb == null) {
            bizObjectModel.setCreatedTime(defaultTemplateModel.getCreatedTime());
            String name = bizSchemaService.getName(bizSchema.getCode(), bizSchema.getName(), bizSchema.getSummary(), bizObjectModel.getData());
            bizObjectModel.setName(name);
            //暂存不生成单据号，提交生成单据号。导入数据状态已完成生成单据号
            if (SequenceStatus.COMPLETED.toString().equals(sequenceStatus) || Objects.equals(Boolean.TRUE, bizObjectModel.getData().get(Integer.MAX_VALUE + "_sequenceNo"))) {
                String sequenceNo = sequenceSettingService.genSequenceNoFromQueue(bizSchema.getCode(), defaultTemplateModel.getFormCode());
                if (StringUtils.isBlank(sequenceNo)) {
                    sequenceNo = sequenceSettingService.createSequenceNo(bizSchema.getCode(), defaultTemplateModel.getFormCode());
                }
                bizObjectModel.setSequenceNo(sequenceNo);
            }
        } else {
            // 覆盖导入 不修改 标题、单据号、创建时间
            bizObjectModel.setId((String) dataDb.get(DefaultPropertyType.ID.getCode()));
            bizObjectModel.setCreatedTime((Date) dataDb.get(DefaultPropertyType.CREATED_TIME.getCode()));
            bizObjectModel.setName((String) dataDb.get(DefaultPropertyType.NAME.getCode()));
            bizObjectModel.setSequenceNo((String) dataDb.get(DefaultPropertyType.SEQUENCE_NO.getCode()));
        }
        bizObjectModel.setModifier(userId);
        bizObjectModel.setModifiedTime(defaultTemplateModel.getModifiedTime());
        bizObjectModel.getData().remove(Integer.MAX_VALUE + "_sequenceNo");

        //校验有没有id 没有就生成uuid
        if (StringUtils.isEmpty(bizObjectModel.getId())) {
            bizObjectModel.setId(genId());
        }
        return new BizObject(bizObjectModel.getSchemaCode(), bizObjectModel.getId(), bizObjectModel.getData());
    }

    private DepartmentModel getDepartmentInUserMap(String userId) {
        if (userDepartmentMap.containsKey(userId)) {
            return userDepartmentMap.get(userId);
        }
        DepartmentModel department = getDepartmentByUserId(userId);
        userDepartmentMap.put(userId, department);
        return department;
    }

    @Override
    public BizObjectModel updateBizObjectModel(String userId, BizObjectModel bizObject, BizSchemaModel bizSchemaModel, BizObjectOptions options) {
        if (bizObject == null) {
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }

        if (StringUtils.isEmpty(bizObject.getFormCode())) {
            List<BizForm> bizForms = bizFormService.getListBySchemaCode(bizObject.getSchemaCode());
            if (CollectionUtils.isNotEmpty(bizForms)) {
                bizObject.setFormCode(bizForms.get(0).getCode());
            }
        }

        bizFormService.verifyControlProperty(bizObject);

        if (log.isTraceEnabled()) {
            log.trace("bizObject json = {}", JSONObject.toJSONString(bizObject));
        }
        if (bizSchemaModel == null) {
            log.debug("数据模型为空，schemaCode = {}", bizObject.getSchemaCode());
            throw new ServiceException(ErrCode.BIZ_SCHEMA_MODEL_NOT_EXIST, bizObject.getSchemaCode());
        }
        if (log.isDebugEnabled()) {
            log.debug("summary = {}", bizSchemaModel.getSummary());
        }

        if (StringUtils.isEmpty(bizObject.getId())) {
            log.debug("objectId is null...");
            //插入bo的方法需要后续完成
            return null;

        } else {
            final BizObject objectExisted = bizObjectService.loadBizObject(bizObject.getSchemaCode(), bizObject.getId(), null);

            if (!objectExisted.isLoadedFromDb()) {
                log.debug("bizObject do not from db...");
                //插入bo的方法需要后续完成
                return null;
            } else {
                log.debug("bizObject from db...");
                //插入bo的方法需要后续完成
                BizSchema bizSchema = ModelUtil.toEntity(bizSchemaModel, BizSchema.class);
                BizObjectModel bizObjectModel = modifiedBizObject(userId, bizSchema, bizObject, objectExisted, options);
                return bizObjectModel;
            }
        }
    }

    @Override
    public List<String> addBizObjects(Boolean exeRuleFlag, String userId, List<BizObjectModel> bizObjects, String queryField) {
        return BizObjectFacade.super.addBizObjects(exeRuleFlag, userId, bizObjects, queryField);
    }

    //系统数据项---单据号
    private String ProcessingSequenceNo(final String userId, final BizObjectModel bizObject, final String schemaCode, final BizSchema bizSchema) {
        String sequenceNo = bizObject.getSequenceNo();
        if (!StringUtils.isEmpty(sequenceNo)) {
            log.info("sequenceNo的数据：sequenceNo={}", JSONObject.toJSONString(sequenceNo));
            List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCode(schemaCode);
            if (CollectionUtils.isNotEmpty(bizQuerys)) {
                String code = bizQuerys.get(0).getCode();
                log.info("code的数据：code={}", JSONObject.toJSONString(code));
                if (!StringUtils.isEmpty(code)) {

                    //处理id查询条件信息
                    List<FilterExpression> filterExprCodes = new ArrayList<>();
                    FilterExpression filterExprCode = FilterExpression.empty;
                    log.info("生成id数据查询条件");
                    //获取数据查询条件
                    filterExprCodes.add(Q.it("sequenceNo", FilterExpression.Op.Eq, bizObject.getSequenceNo()));
                    filterExprCode = filterExprCodes.get(0);
                    BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
                    bizObjectQueryModel.setFilterExpr(filterExprCode);
                    bizObjectQueryModel.setSchemaCode(schemaCode);
                    //分页信息
                    int page = 0;
                    int size = Integer.MAX_VALUE;
                    PageableImpl pageable = new PageableImpl(page * size, size);
                    bizObjectQueryModel.setPageable(pageable);
                    bizObjectQueryModel.setQueryCode(code);
                    Page<BizObjectModel> bizObjectModelPage = queryBizObjects(bizObjectQueryModel);
                    List<? extends BizObjectModel> content = bizObjectModelPage.getContent();
                    if (!CollectionUtils.isEmpty(content)) {
                        BizObjectModel bizObjectModel = content.get(0);
                        String bizObjectModelId = bizObjectModel.getId();
                        BizObjectCreatedModel bizObjectDb = getBizObject(userId, schemaCode, bizObjectModelId);
                        String sequenceNoDb = bizObjectDb.getSequenceNo();
                        if (log.isDebugEnabled()) {
                            log.debug("bizObjectModelId的数据：bizObjectModelId={}", bizObjectModelId);
                            log.info("sequenceNoDb的数据：sequenceNoDb={}", JSONObject.toJSONString(sequenceNoDb));
                        }
                        if (sequenceNo.equals(sequenceNoDb)) {
                            Map<String, Object> data = bizObjectModel.getData();
                            String schemaCode1 = bizObjectModel.getSchemaCode();
                            String id = bizObjectModel.getId();
                            data.put(DefaultPropertyType.NAME.getCode(), bizObjectDb.getName());
                            data.put(DefaultPropertyType.CREATED_TIME.getCode(), bizObjectDb.getCreatedTime());
                            BizObject exitBizObject = new BizObject(schemaCode1, id, data);
                            this.tagChildTableDataTODeleted(schemaCode, bizObject, exitBizObject);
                            return updateBizObject(userId, bizSchema, bizObject, exitBizObject, Boolean.TRUE);
                        }
                    }
                }
            }
        }
        return createBizObject(userId, bizSchema, bizObject);
    }

    // 系统数据项---数据标题
    private String ProcessingName(final String userId, final BizObjectModel bizObject, final String schemaCode, final BizSchema bizSchema) {
        String name = bizObject.getName();
        log.info("数据标题：name={}", JSONObject.toJSONString(name));
        if (!StringUtils.isEmpty(name)) {
            List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCode(schemaCode);
            if (CollectionUtils.isNotEmpty(bizQuerys)) {
                String code = bizQuerys.get(0).getCode();
                log.info("列表编码：code={}", JSONObject.toJSONString(code));
                if (!StringUtils.isEmpty(code)) {
                    List<FilterExpression> filterExprNames = new ArrayList<>();
                    FilterExpression filterExprName = FilterExpression.empty;
                    log.info("生成id数据查询条件");
                    //获取数据查询条件
                    filterExprNames.add(Q.it("name", FilterExpression.Op.Eq, bizObject.getName()));
                    filterExprName = filterExprNames.get(0);
                    BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
                    bizObjectQueryModel.setFilterExpr(filterExprName);
                    bizObjectQueryModel.setSchemaCode(schemaCode);
                    //分页信息
                    int page = 0;
                    int size = Integer.MAX_VALUE;
                    PageableImpl pageable = new PageableImpl(page * size, size);
                    bizObjectQueryModel.setPageable(pageable);
                    bizObjectQueryModel.setQueryCode(code);
                    Page<BizObjectModel> bizObjectModelPage = queryBizObjects(bizObjectQueryModel);
                    List<? extends BizObjectModel> content = bizObjectModelPage.getContent();
                    if (!CollectionUtils.isEmpty(content)) {
                        BizObjectModel defaultBizObjectModel = content.get(0);
                        String bizObjectId = defaultBizObjectModel.getId();
                        log.info("bizObjectId的数据：bizObjectId={}", JSONObject.toJSONString(bizObjectId));
                        BizObjectCreatedModel bizObjectDb = getBizObject(userId, schemaCode, bizObjectId);
                        String nameDb = bizObjectDb.getName();
                        if (name.equals(nameDb)) {
                            Map<String, Object> data = bizObjectDb.getData();
                            String schemaCode1 = bizObjectDb.getSchemaCode();
                            String id = bizObjectDb.getId();
                            data.put(DefaultPropertyType.SEQUENCE_NO.getCode(), bizObjectDb.getSequenceNo());
                            data.put(DefaultPropertyType.CREATED_TIME.getCode(), bizObjectDb.getCreatedTime());
                            BizObject exitBizObject = new BizObject(schemaCode1, id, data);
                            this.tagChildTableDataTODeleted(schemaCode, bizObject, exitBizObject);
                            return updateBizObject(userId, bizSchema, bizObject, exitBizObject, Boolean.TRUE);
                        }
                    }
                }
            }
        }

        return createBizObject(userId, bizSchema, bizObject);
    }

    //已发布短文本数据项
    private String ProcessingShortText(final String userId, final BizObjectModel bizObject, final String schemaCode, final BizSchema bizSchema, final String queryField) {
        List<BizProperty> properties = bizPropertyService.getListBySchemaCode(schemaCode, true);
        properties = properties.stream().filter(propertyModel -> (propertyModel.getPublished() && (!propertyModel.getDefaultProperty()))).collect(Collectors.toList());
        log.info("业务数据项：properties={}", JSONObject.toJSONString(properties.toString()));
        if (CollectionUtils.isEmpty(properties)) {
            return createBizObject(userId, bizSchema, bizObject);
        }
        List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCode(schemaCode);
        for (BizProperty bizPropertyMode : properties) {
            if (!(bizPropertyMode.getPropertyType() == BizPropertyType.SHORT_TEXT)) {
                continue;
            }
            if (!queryField.equals(bizPropertyMode.getCode())) {
                continue;
            }
            Object propertyValue = bizObject.getData().get(bizPropertyMode.getCode());
            if (Objects.isNull(propertyValue) || StringUtils.isEmpty(propertyValue.toString())) {
                continue;
            }
            if (CollectionUtils.isEmpty(bizQuerys)) {
                continue;
            }
            String code = bizQuerys.get(0).getCode();
            if (StringUtils.isEmpty(code)) {
                continue;
            }
            List<FilterExpression> filterExprValues = new ArrayList<>();
            FilterExpression filterExprValue = FilterExpression.empty;
            log.info("生成id数据查询条件");
            //获取数据查询条件
            filterExprValues.add(Q.it(queryField, FilterExpression.Op.Eq, bizObject.getData().get(bizPropertyMode.getCode())));
            filterExprValue = filterExprValues.get(0);
            BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
            bizObjectQueryModel.setFilterExpr(filterExprValue);
            //分页信息
            int page = 0;
            int size = Integer.MAX_VALUE;
            PageableImpl pageable = new PageableImpl(page * size, size);
            bizObjectQueryModel.setPageable(pageable);
            bizObjectQueryModel.setSchemaCode(schemaCode);
            bizObjectQueryModel.setQueryCode(code);
            Page<BizObjectModel> bizObjectModelPage = queryBizObjects(bizObjectQueryModel);
            List<? extends BizObjectModel> content = bizObjectModelPage.getContent();
            if (CollectionUtils.isEmpty(content)) {
                continue;
            }
            for (BizObjectModel bizObjectModel : content) {
                String bizObjectModelId = bizObjectModel.getId();
                log.info("bizObjectModelId的数据：bizObjectModelId={}", JSONObject.toJSONString(bizObjectModelId));
                BizObjectCreatedModel bizObjectDb = getBizObject(userId, schemaCode, bizObjectModelId);
                Object propertyDb = bizObjectDb.getData().get(bizPropertyMode.getCode());
                if (propertyValue.equals(propertyDb)) {
                    Map<String, Object> data = bizObjectModel.getData();
                    String schemaCode1 = bizObjectModel.getSchemaCode();
                    String id = bizObjectModel.getId();
                    data.put(DefaultPropertyType.SEQUENCE_NO.getCode(), bizObjectDb.getSequenceNo());
                    data.put(DefaultPropertyType.NAME.getCode(), bizObjectDb.getName());
                    data.put(DefaultPropertyType.CREATED_TIME.getCode(), bizObjectDb.getCreatedTime());
                    BizObject exitBizObject = new BizObject(schemaCode1, id, data);
                    this.tagChildTableDataTODeleted(schemaCode, bizObject, exitBizObject);
                    return updateBizObject(userId, bizSchema, bizObject, exitBizObject, Boolean.TRUE);
                }
            }
        }
        return createBizObject(userId, bizSchema, bizObject);
    }

    /**
     * 子表增量提交模式，标记历史字表数据为删除状态
     *
     * @param schemaCode
     * @param bizObject
     * @param objectExisted
     */
    private void tagChildTableDataTODeleted(String schemaCode, BizObjectModel bizObject, BizObject objectExisted) {
        List<BizProperty> properties = bizPropertyService.getListBySchemaCode(schemaCode, true);
        if (org.springframework.util.CollectionUtils.isEmpty(properties)) {
            return;
        }

        List<BizProperty> childTablePropertys = properties.stream().filter(bizProperty -> bizProperty.getPropertyType() == BizPropertyType.CHILD_TABLE).collect(Collectors.toList());
        if (org.springframework.util.CollectionUtils.isEmpty(childTablePropertys)) {
            return;
        }

        childTablePropertys.stream().forEach(bizProperty -> {
            List<Map<String, Object>> childTables = (List<Map<String, Object>>) objectExisted.getData().get(bizProperty.getCode());
            if (org.springframework.util.CollectionUtils.isEmpty(childTables)) {
                return;
            }

            childTables.stream().forEach(map -> {
                map.put(BizObject.DATAROWSTATUS, DataRowStatus.Deleted.name());
            });

            if (bizObject.getData().get(bizProperty.getCode()) == null) {
                bizObject.getData().put(bizProperty.getCode(), childTables);
            } else {
                ((List<Map<String, Object>>) bizObject.getData().get(bizProperty.getCode())).addAll(childTables);
            }
        });
    }

    /**
     * 根据业务对象ID 关联到流程实例表 再根据流程实例ID关联到 biz_workflow表中是否存在数据 不为空则流程还未启动或表单未关联任何流程
     *
     * @param bizObjectId
     * @return
     */
    private Boolean isFormBindWorkflowInstance(String bizObjectId) {
        if (log.isDebugEnabled()) {
            log.debug("开始查询业务表单是否关联流程实例，业务对象ID{}", bizObjectId);
        }
        Assert.notNull(bizObjectId, " isFormBindWorkflowInstance bizObjectId is null");
        WorkflowInstanceModel bizWorkflowInstance = bizWorkflowInstanceService.getByObjectId(bizObjectId);
        //流程实例表为空，则表单未关联流程
        if (Objects.isNull(bizWorkflowInstance)) {
            return Boolean.FALSE;
        }
        String instanceId = bizWorkflowInstance.getId();
        List<WorkItemModel> bizWorkItemList = bizWorkitemService.getListByInstanceId(instanceId);
        List<WorkItemModel> bizWorkItemFinishedList = bizWorkitemFinishedService.getListByInstanceId(instanceId);
        //流程待办列表为空&流程已完成列表都为空，则表单未关联流程实例
        if (CollectionUtils.isEmpty(bizWorkItemFinishedList) && CollectionUtils.isEmpty(bizWorkItemList)) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 业务对象不存在，创建业务对象
     *
     * @param userId    用户id
     * @param bizObject 业务对象
     * @param bizSchema 业务模型
     * @return objectId
     */
    private String createBizObject(final String userId, final BizSchema bizSchema, final BizObjectModel bizObject) {
        if (log.isDebugEnabled()) {
            log.debug("bizObject： bizobject={}", JSONObject.toJSONString(bizObject));
        }
        String boCreate = bizObject.getString(DefaultPropertyType.CREATER.getCode());
        String createBy = StringUtils.isEmpty(boCreate) ? userId : boCreate;
        bizObject.setCreater(createBy);

        String owner = bizObject.getString(DefaultPropertyType.OWNER.getCode());
        if (StringUtils.isEmpty(owner)) {
            owner = userId;
            bizObject.setOwner(owner);
        }
        String sequenceStatus = bizObject.getString(DefaultPropertyType.SEQUENCE_STATUS.getCode());
        if (StringUtils.isEmpty(sequenceStatus)) {
            bizObject.setSequenceStatus(WorkflowInstanceStatus.PROCESSING.toString());
        }

        DepartmentModel department = null;
        Object createdDeptId = bizObject.getData().get(DefaultPropertyType.CREATED_DEPT_ID.getCode());
        if (Objects.nonNull(createdDeptId)) {
            department = departmentFacade.get(createdDeptId.toString());
        } else {
            department = getDepartmentByUserId(createBy);
            if (Objects.nonNull(department)) {
                bizObject.setCreatedDeptId(department.getId());
            }
        }

        //设置所属人部门
        Object boOwnerDepartment = bizObject.getObject(DefaultPropertyType.OWNER_DEPT_ID.getCode());
        if (boOwnerDepartment == null) {
            String ownerId = getIdFromObject(bizObject.get(DefaultPropertyType.OWNER.getCode()));
            if (!createBy.equals(ownerId)) {
                DepartmentModel ownerDepartment = getDepartmentByUserId(ownerId);
                if (ownerDepartment != null) {
                    bizObject.setOwnerDeptId(ownerDepartment.getId());
                    bizObject.setOwnerDeptQueryCode(ownerDepartment.getQueryCode());
                }
            } else if (department != null) {
                bizObject.setOwnerDeptId(department.getId());
                bizObject.setOwnerDeptQueryCode(department.getQueryCode());
            }
        } else {
            DepartmentModel ownerDepartment;
            String ownerDepartmentId = this.getSelectionId(boOwnerDepartment, DefaultPropertyType.OWNER_DEPT_ID.getCode());
            if (department != null && ownerDepartmentId.equals(department.getId())) {
                ownerDepartment = department;
            } else {
                ownerDepartment = this.departmentFacade.get(ownerDepartmentId);
            }
            if (ownerDepartment != null) {
                bizObject.setOwnerDeptId(ownerDepartment.getId());
                bizObject.setOwnerDeptQueryCode(ownerDepartment.getQueryCode());
            }
        }

        bizObject.setModifier(userId);
        //处理毫秒
        Date date = parseData(new Date());
        bizObject.setCreatedTime(date);
        bizObject.setModifiedTime(new Date());
        //暂存不生成单据号，提交生成单据号。导入数据状态已完成生成单据号
        if (SequenceStatus.COMPLETED.toString().equals(bizObject.getSequenceStatus())
                || Objects.equals(Boolean.TRUE, bizObject.getData().get(Integer.MAX_VALUE + "_sequenceNo"))) {
            String sequenceNo = sequenceSettingService.createSequenceNo(bizSchema.getCode(), bizObject.getFormCode());
            bizObject.setSequenceNo(sequenceNo);
        }
        bizObject.getData().remove(Integer.MAX_VALUE + "_sequenceNo");

        String name = bizSchemaService.getName(bizSchema.getCode(), bizSchema.getName(), bizSchema.getSummary(), bizObject.getData());
        bizObject.setName(name);

        //校验有没有id 没有就生成uuid
        String id = null;
        if (StringUtils.isEmpty(bizObject.getId())) {
            id = genId();
        } else {
            id = bizObject.getId();
        }
        BizObject bo = new BizObject(bizObject.getSchemaCode(), id, bizObject.getData());
        Object objId = bo.getData().get("id");
        if (Objects.isNull(objId)) {
            bo.getData().put("id", bo.getId());
        }
        String objectId = null;
        try {
            ThreadLocalAttributes.setThreadAttribute("currentUserId", userId);
            objectId = bizObjectService.createBizObject(bo);
        } catch (Exception e) {
            throw e;
        } finally {
            ThreadLocalAttributes.removeThreadAttribute("currentUserId");
        }
        log.info("object id = {}", objectId);
        return objectId;
    }

    private String genId() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }


    private Date parseData(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 更新业务对象
     *
     * @param userId        用户id
     * @param bizSchema     业务模型
     * @param bizObject     表单传递过来的业务对象
     * @param objectExisted 数据库存在的业务对象
     * @return objectId
     */
    private String updateBizObject(String userId, BizSchema bizSchema, BizObjectModel bizObject, BizObject objectExisted, Boolean syncInstance) {
        return updateBizObject(userId, bizSchema, bizObject, objectExisted, syncInstance, null);
    }

    /**
     * 更新业务对象
     *
     * @param userId        用户id
     * @param bizSchema     业务模型
     * @param bizObject     表单传递过来的业务对象
     * @param objectExisted 数据库存在的业务对象
     * @param options       orm参数(可选)
     * @return objectId
     */
    private String updateBizObject(String userId, BizSchema bizSchema, BizObjectModel bizObject, BizObject objectExisted,
                                   Boolean syncInstance, BizObjectOptions options) {
        log.debug("update bizObject...");
        // 查询bo数据，避免生成摘要时丢失信息
        final BizObjectCreatedModel oldBizObject = new BizObjectCreatedModel(bizObject.getSchemaCode(), objectExisted.getData(), false);
        if (log.isTraceEnabled()) {
            log.trace("获取原表单数据:{}", JSON.toJSONString(oldBizObject));
            log.trace("当前表单数据:{}", JSON.toJSONString(bizObject));
        }

        String create = bizObject.getString(DefaultPropertyType.CREATER.getCode());
        log.info("=====================create================ {}", create);
        if (StringUtils.isEmpty(create)) {
            String createId = oldBizObject.getCreater() != null ? oldBizObject.getCreater().getId() : null;
            log.debug("获取到的用户ID:{}", createId);
            String uid = StringUtils.isEmpty(createId) ? userId : createId;
            bizObject.setCreater(uid);

            DepartmentModel department = getDepartmentByUserId(uid);
            if (department != null) {
                bizObject.setCreatedDeptId(department.getId());
            }
        }

        String createdTime = bizObject.getString(DefaultPropertyType.CREATED_TIME.getCode());
        log.info("=====================createdTime================ {}", createdTime);
        if (StringUtils.isEmpty(createdTime)) {
            bizObject.setCreatedTime(oldBizObject.getCreatedTime());
        }

        this.setOwner(bizObject, oldBizObject, userId);
        Object boOwner = bizObject.getObject(DefaultPropertyType.OWNER.getCode());
        String ownerId = this.getSelectionId(boOwner, DefaultPropertyType.OWNER.getCode());
        UserModel ownerUser = this.userFacade.get(ownerId);
        log.info("=====================ownerUser================ {}", ownerUser);

        Object boOwnerDepartment = bizObject.getObject(DefaultPropertyType.OWNER_DEPT_ID.getCode());
        String ownerDepartmentId;
        log.info("=====================boOwnerDepartment================ {}", boOwnerDepartment);
        //修改时未提交拥有者部门id，使用数据库旧有数据的拥有者部门ID。
        if (boOwnerDepartment == null) {
            boOwnerDepartment = oldBizObject.getObject(DefaultPropertyType.OWNER_DEPT_ID.getCode());
        }
        if (boOwnerDepartment == null) {
            ownerDepartmentId = ownerUser == null ? null : ownerUser.getDepartmentId();
        } else {
            ownerDepartmentId = this.getSelectionId(boOwnerDepartment, DefaultPropertyType.OWNER_DEPT_ID.getCode());
        }
        bizObject.setOwnerDeptId(ownerDepartmentId);
        DepartmentModel ownerDepartment = this.departmentFacade.get(ownerDepartmentId);
        if (ownerDepartment != null) {
            bizObject.setOwnerDeptQueryCode(ownerDepartment.getQueryCode());
        }

        String creater = getIdFromObject(bizObject.get(DefaultPropertyType.CREATER.getCode()));
        boolean createDeptChanged = false;
        if (creater != null && creater.equals(ownerId)) {//如果创建人和拥护者是同一个人，部门保存一致
            Object oldCreateDepartment = oldBizObject.getObject(DefaultPropertyType.CREATED_DEPT_ID.getCode());
            if (oldCreateDepartment != null) {
                String oldCreateDepartmentId = this.getSelectionId(oldCreateDepartment, DefaultPropertyType.CREATED_DEPT_ID.getCode());
                if (!StringUtils.isEmpty(oldCreateDepartmentId) && !oldCreateDepartmentId.equals(ownerDepartmentId)) {
                    bizObject.setCreatedDeptId(ownerDepartmentId);
                    createDeptChanged = true;
                }
            }
        }

        //当修改时原数据没有单据号，暂存操作不生成单据号，提交操作生成单据号。导入操作数据状态已完成生成单据号
        if (StringUtils.isEmpty(oldBizObject.getSequenceNo())
                && (SequenceStatus.COMPLETED.toString().equals(bizObject.getSequenceStatus()) || Objects.equals(Boolean.TRUE, bizObject.getData().get(Integer.MAX_VALUE + "_sequenceNo")))) {
            String sequenceNo = sequenceSettingService.createSequenceNo(bizSchema.getCode(), bizObject.getFormCode());
            bizObject.setSequenceNo(sequenceNo);
        } else {
            if (!(StringUtils.isEmpty(oldBizObject.getSequenceNo()))) {
                bizObject.setSequenceNo(oldBizObject.getSequenceNo());
            }
        }
        Object remove = bizObject.getData().remove(Integer.MAX_VALUE + "_sequenceNo");
        if (null != remove) {
            log.info("单据号：remove={}", JSONObject.toJSONString(remove.toString()));
        }

        bizObject.setModifier(userId);
        bizObject.setModifiedTime(new Date());

        Map<String, Object> nameInfo = new HashMap<>();
        nameInfo.putAll(bizObject.getData());
        nameInfo.put(DefaultPropertyType.CREATER.getCode(), oldBizObject.getCreater().getId());
        String name = bizSchemaService.getName(bizSchema.getCode(), bizSchema.getName(), bizSchema.getSummary(), nameInfo);

        bizObject.setName(name);
        if (log.isDebugEnabled()) {
            log.info("=====================bizObject================ {}", bizObject);
        }
        //修改时不能修改以下字段
        bizObject.getData().remove(DefaultPropertyType.CREATER.getCode());
        bizObject.getData().remove(DefaultPropertyType.CREATED_TIME.getCode());

        if (!createDeptChanged) {
            bizObject.getData().remove(DefaultPropertyType.CREATED_DEPT_ID.getCode());
        }

        if (log.isTraceEnabled()) {
            log.trace("bizObject json2 = {}", JSONObject.toJSONString(bizObject.getData()));
        }

        String wfInstanceId = oldBizObject.getWorkflowInstanceId();
        if (StringUtils.isBlank(wfInstanceId)) {
            WorkflowInstanceModel bizWorkflowInstance = bizWorkflowInstanceService.getByObjectId(oldBizObject.getId());
            wfInstanceId = bizWorkflowInstance == null ? wfInstanceId : bizWorkflowInstance.getId();
            bizObject.setWorkflowInstanceId(wfInstanceId);
        }

        try {
            ThreadLocalAttributes.setThreadAttribute("currentUserId", userId);
            ThreadLocalAttributes.removeThreadAttribute("triggerData");
            if (StringUtils.isNotBlank(objectExisted.getId())) {
                bizObject.getData().put(DefaultPropertyType.ID.getCode(), objectExisted.getId());
            }
            bizObjectService.updateBizObject(new BizObject(bizObject.getSchemaCode(), objectExisted.getId(), bizObject.getData(), objectExisted), options);
        } catch (Exception e) {
            throw e;
        } finally {
            ThreadLocalAttributes.removeThreadAttribute("currentUserId");
        }
        return bizObject.getId();
    }

    /**
     * 更新业务对象
     *
     * @param userId        用户id
     * @param bizSchema     业务模型
     * @param bizObject     表单传递过来的业务对象
     * @param objectExisted 数据库存在的业务对象
     * @return objectId
     */
    private BizObjectModel modifiedBizObject(String userId, BizSchema bizSchema, BizObjectModel bizObject, BizObject objectExisted, BizObjectOptions options) {
        log.debug("update bizObject...");
        // 查询bo数据，避免生成摘要时丢失信息
        final BizObjectCreatedModel oldBizObject = new BizObjectCreatedModel(bizObject.getSchemaCode(), objectExisted.getData(), false);
        if (log.isTraceEnabled()) {
            log.trace("获取原表单数据:{}", JSON.toJSONString(oldBizObject));
            log.trace("当前表单数据:{}", JSON.toJSONString(bizObject));
        }

        String create = bizObject.getString(DefaultPropertyType.CREATER.getCode());
        log.info("=====================create================ {}", create);
        if (StringUtils.isEmpty(create)) {
            String createId = oldBizObject.getCreater() != null ? oldBizObject.getCreater().getId() : null;
            log.debug("获取到的用户ID:{}", createId);
            String uid = StringUtils.isEmpty(createId) ? userId : createId;
            bizObject.setCreater(uid);

            DepartmentModel department = getDepartmentByUserId(uid);
            if (department != null) {
                bizObject.setCreatedDeptId(department.getId());
            }
        }

        String createdTime = bizObject.getString(DefaultPropertyType.CREATED_TIME.getCode());
        log.info("=====================createdTime================ {}", createdTime);
        if (StringUtils.isEmpty(createdTime)) {
            bizObject.setCreatedTime(oldBizObject.getCreatedTime());
        }

        this.setOwner(bizObject, oldBizObject, userId);
        Object boOwner = bizObject.getObject(DefaultPropertyType.OWNER.getCode());
        String ownerId = this.getSelectionId(boOwner, DefaultPropertyType.OWNER.getCode());
        UserModel ownerUser = this.userFacade.get(ownerId);
        log.info("=====================ownerUser================ {}", ownerUser);

        Object boOwnerDepartment = bizObject.getObject(DefaultPropertyType.OWNER_DEPT_ID.getCode());
        String ownerDepartmentId;
        log.info("=====================boOwnerDepartment================ {}", boOwnerDepartment);
        //修改时未提交拥有者部门id，使用数据库旧有数据的拥有者部门ID。
        if (boOwnerDepartment == null) {
            boOwnerDepartment = oldBizObject.getObject(DefaultPropertyType.OWNER_DEPT_ID.getCode());
        }
        if (boOwnerDepartment == null) {
            ownerDepartmentId = ownerUser == null ? null : ownerUser.getDepartmentId();
        } else {
            ownerDepartmentId = this.getSelectionId(boOwnerDepartment, DefaultPropertyType.OWNER_DEPT_ID.getCode());
        }
        bizObject.setOwnerDeptId(ownerDepartmentId);
        DepartmentModel ownerDepartment = this.departmentFacade.get(ownerDepartmentId);
        if (ownerDepartment != null) {
            bizObject.setOwnerDeptQueryCode(ownerDepartment.getQueryCode());
        }

        //当修改时原数据没有单据号，暂存操作不生成单据号，提交操作生成单据号。导入操作数据状态已完成生成单据号
        if (StringUtils.isEmpty(oldBizObject.getSequenceNo())
                && (SequenceStatus.COMPLETED.toString().equals(bizObject.getSequenceStatus()) || Objects.equals(Boolean.TRUE, bizObject.getData().get(Integer.MAX_VALUE + "_sequenceNo")))) {
            String sequenceNo = sequenceSettingService.createSequenceNo(bizSchema.getCode(), bizObject.getFormCode());
            bizObject.setSequenceNo(sequenceNo);
        } else {
            if (!(StringUtils.isEmpty(oldBizObject.getSequenceNo()))) {
                bizObject.setSequenceNo(oldBizObject.getSequenceNo());
            }
        }
        Object remove = bizObject.getData().remove(Integer.MAX_VALUE + "_sequenceNo");

        if (null != remove) {
            log.info("单据号：remove={}", JSONObject.toJSONString(remove.toString()));
        }

        bizObject.setModifier(userId);
        bizObject.setModifiedTime(new Date());

        Map<String, Object> nameInfo = mergeObject(bizObject, objectExisted);
        nameInfo.put(DefaultPropertyType.CREATER.getCode(), oldBizObject.getCreater().getId());
        String name = bizSchemaService.getName(bizSchema.getCode(), bizSchema.getName(), bizSchema.getSummary(), nameInfo);

        bizObject.setName(name);
        log.info("=====================bizObject================ {}", bizObject);
        //修改时不能修改以下字段
        bizObject.getData().remove(DefaultPropertyType.CREATER.getCode());
        bizObject.getData().remove(DefaultPropertyType.CREATED_TIME.getCode());
        bizObject.getData().remove(DefaultPropertyType.CREATED_DEPT_ID.getCode());

        if (log.isTraceEnabled()) {
            log.debug("bizObject json2 = {}", JSONObject.toJSONString(bizObject.getData()));
        }

        String wfInstanceId = oldBizObject.getWorkflowInstanceId();
        if (StringUtils.isBlank(wfInstanceId)) {
            WorkflowInstanceModel bizWorkflowInstance = bizWorkflowInstanceService.getByObjectId(oldBizObject.getId());
            wfInstanceId = bizWorkflowInstance == null ? wfInstanceId : bizWorkflowInstance.getId();
            bizObject.setWorkflowInstanceId(wfInstanceId);
        }
        BizObject obj = new BizObject(bizObject.getSchemaCode(), objectExisted.getId(), bizObject.getData(), objectExisted);
        bizObjectService.modifiedBizObject(obj, options);
        return new BizObjectModel(bizObject.getSchemaCode(), obj.getData(), false);
    }

    private Map<String, Object> mergeObject(BizObjectModel bizObject, BizObject objectExisted) {
        Map<String, Object> map = Maps.newHashMap();
        if (bizObject != null && MapUtils.isNotEmpty(bizObject.getData())) {
            map.putAll(bizObject.getData());
        }
        if (objectExisted != null && MapUtils.isNotEmpty(objectExisted.getData())) {
            objectExisted.getData().forEach(map::putIfAbsent);
        }
        return map;
    }

    /**
     * 取选人/部门的id
     *
     * @param value
     * @param code
     * @return
     */
    private String getSelectionId(Object value, String code) {
        BizProperty bizProperty = new BizProperty();
        bizProperty.setCode(code);
        bizProperty.setPropertyType(BizPropertyType.SELECTION);
        String ownerDepartmentId = (String) this.bizObjectConverter.fromFormValue(value, bizProperty);
        return ownerDepartmentId;
    }

    private void setOwner(BizObjectModel bizObject, BizObjectCreatedModel oldBizObject, String userId) {
        String boOwner = bizObject.getString(DefaultPropertyType.OWNER.getCode());
        if (StringUtils.isEmpty(boOwner)) {
            String ownerId = (oldBizObject.getOwner() != null) ? oldBizObject.getOwner().getId() : null;
            String owner = StringUtils.isEmpty(ownerId) ? userId : ownerId;
            bizObject.setOwner(owner);
        }
    }

    @Override
    public Boolean removeBizObject(String userId, String schemaCode, String objectId) {
        if (Strings.isNullOrEmpty(userId)) {
            throw new ServiceException(ErrCode.ORG_USER_ID_EMPTY);
        }
        if (Strings.isNullOrEmpty(schemaCode)) {
            throw new ServiceException(ErrCode.BIZ_SCHEMA_CODE_EMPTY);
        }
        if (Strings.isNullOrEmpty(objectId)) {
            throw new ServiceException(ErrCode.BIZ_OBJECT_ID_EMPTY);
        }

        try {
            ThreadLocalAttributes.setThreadAttribute("currentUserId", userId);
            bizObjectService.deleteBizObject(schemaCode, objectId);
        } catch (Exception e) {
            throw e;
        } finally {
            ThreadLocalAttributes.removeThreadAttribute("currentUserId");
        }
        return Boolean.TRUE;
    }


    public Page<BizObjectModel> queryTransferBizObjects(BizObjectQueryModel bizObjectQueryModel) {
        final String schemaCode = bizObjectQueryModel.getSchemaCode();
        final String queryCode = bizObjectQueryModel.getQueryCode();
        if (StringUtils.isEmpty(schemaCode) && StringUtils.isEmpty(queryCode)) {
            log.debug("bizQuery is null. {}", ErrCode.BIZ_QUERY_CODE_SCHEMACODE_NOT_EXIST.getErrMsg());
            return new PageImpl<>(0L, Lists.newArrayList());
        }
        //获取第一个列表
        final List<BizQuery> bizQuerys = bizQueryService.getListBySchemaCode(schemaCode);
        if (CollectionUtils.isEmpty(bizQuerys)) {
            log.debug("bizQuery is null. {}", queryCode);
            return new PageImpl<>(0L, Lists.newArrayList());
        }
        //判断当前表是否存在
        if (!db.ddl().tableExist(schemaCode)) {
            log.error("业务表:{} 不存在", schemaCode);
            return new PageImpl<>(0L, Lists.newArrayList());
        }

        //判断数据项是否存在
        String queryId = bizQuerys.get(0).getId();
        //排序信息
        final List<OrderImpl> orders = new ArrayList<>();
        //使用默认排序
        orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));

        final List<String> columnList = Lists.newArrayList();
        columnList.add(DefaultPropertyType.ID.getCode());
        columnList.add(DefaultPropertyType.NAME.getCode());
        columnList.add(DefaultPropertyType.OWNER_DEPT_ID.getCode());
        columnList.add(DefaultPropertyType.CREATED_TIME.getCode());
        columnList.add(DefaultPropertyType.SEQUENCE_STATUS.getCode());

        if (log.isDebugEnabled()) {
            log.debug("==================columnList={}", columnList);
        }
        Page<Map<String, Object>> queryData = null;
        try {
            queryData = bizObjectService.queryBizObjectsWithNoBind(new BizObjectQueryObject() {
                @Override
                public String getSchemaCode() {
                    return schemaCode;
                }

                @Override
                public FilterExpression getFilterExpression() {
                    return bizObjectQueryModel.getFilterExpr();
                }

                @Override
                public List<String> getDisplayFields() {
                    columnList.add(DefaultPropertyType.ID.getCode());
                    columnList.add(0, DefaultPropertyType.NAME.getCode());
                    if (!columnList.contains(DefaultPropertyType.OWNER.getCode())) {
                        columnList.add(DefaultPropertyType.OWNER.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.CREATER.getCode())) {
                        columnList.add(DefaultPropertyType.CREATER.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.CREATED_TIME.getCode())) {
                        columnList.add(DefaultPropertyType.CREATED_TIME.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.MODIFIED_TIME.getCode())) {
                        columnList.add(DefaultPropertyType.MODIFIED_TIME.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
                        columnList.add(DefaultPropertyType.SEQUENCE_STATUS.getCode());
                    }
                    return columnList;
                }


                @Override
                public Pageable getPageable() {
                    return bizObjectQueryModel.getPageable();
                }

                @Override
                public Sortable getSortable() {
                    return orders == null ? null : new SortableImpl(orders);
                }
            });
        } catch (Exception e) {
            log.info("工作交接schemaCode:{},queryCode{},异常数据：{}", schemaCode, queryCode, e);
            return new PageImpl<>(0L, Lists.newArrayList());
        }
        final List<BizObjectModel> bizObjectList = new ArrayList<>();
        for (Map<String, Object> map : queryData.getContent()) {
            final BizObjectModel bizObjectModel = new BizObjectModel(schemaCode, map, false);
            bizObjectList.add(bizObjectModel);
        }
        if (log.isTraceEnabled()) {
            log.trace("==================bizObjectList= {}", JSON.toJSONString(bizObjectList));
        }
        return new PageImpl<>(queryData.getTotal(), bizObjectList);
    }

    @Override
    public Page<BizObjectModel> queryBizObjects(BizObjectQueryModel bizObjectQueryModel) {
        final String schemaCode = bizObjectQueryModel.getSchemaCode();
        final String queryCode = bizObjectQueryModel.getQueryCode();
        final ClientType clientType = Objects.nonNull(bizObjectQueryModel.getClientType()) ? bizObjectQueryModel.getClientType() : ClientType.PC;
        if (StringUtils.isEmpty(schemaCode) && StringUtils.isEmpty(queryCode)) {
            throw new ServiceException(ErrCode.BIZ_QUERY_CODE_SCHEMACODE_NOT_EXIST, bizObjectQueryModel);
        }

        final BizQuery bizQuery = bizQueryService.getBySchemaCodeAndCode(schemaCode, queryCode);
        if (bizQuery == null) {
            log.debug("bizQuery is null. {}", queryCode);
            throw new ServiceException(ErrCode.BIZ_QUERY_NOT_EXIST, queryCode);
        }
        String queryId = bizQuery.getId();
        //排序信息
        List<BizQuerySort> sorts = bizQuerySortService.getListByQueryId(queryId);
        sorts = sorts.stream().filter(t -> Objects.equals(clientType, t.getClientType())).collect(Collectors.toList());
        final List<OrderImpl> orders = new ArrayList<>();
        if (CollectionUtils.isEmpty(sorts)) {
            //使用默认排序
            orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));
        } else {
            orders.addAll(getOrders(sorts));
        }
        //查询数据的方法
        List<BizProperty> properties = bizPropertyService.getListBySchemaCode(schemaCode, true);
        if (CollectionUtils.isEmpty(properties)) {
            return new PageImpl<BizObjectModel>(0, Lists.newArrayList());
        }
        List<String> propertyCodes = properties.stream().filter(property -> property != null).map(BizProperty::getCode).collect(Collectors.toList());
        List<String> columns = Lists.newArrayList();
        Boolean display = bizObjectQueryModel.getDisplay();
        columns = listQueryColumn(schemaCode, queryCode, queryId, bizObjectQueryModel.getOptions(), clientType, display);
        List<String> columnList = columns.stream().filter(code -> propertyCodes.contains(code)).collect(Collectors.toList());
        if (log.isDebugEnabled()) {
            log.debug("==================columnList=", columnList);
        }

        final Page<Map<String, Object>> queryData = bizObjectService.queryBizObjects(new BizObjectQueryObject() {

            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {
                return bizObjectQueryModel.getFilterExpr();
            }

            @Override
            public List<String> getDisplayFields() {
                return completeSystemFields(schemaCode, bizObjectQueryModel.getQuotes(), columnList);
            }

            @Override
            public Pageable getPageable() {
                return bizObjectQueryModel.getPageable();
            }

            @Override
            public Sortable getSortable() {
                return orders == null ? null : new SortableImpl(orders);
            }

            @Override
            public Map<String, Object> getQuotes() {
                return bizObjectQueryModel.getQuotes();
            }
        });
        //转换WEB-API需要的数据
        final List<BizObjectModel> bizObjectList = new ArrayList<>();
        for (Map<String, Object> map : queryData.getContent()) {
            final BizObjectModel bizObjectModel = new BizObjectModel(schemaCode, map, false);
            bizObjectList.add(bizObjectModel);
        }
        if (log.isTraceEnabled()) {
            log.trace("==================bizObjectList={}", JSON.toJSONString(bizObjectList));
        }
        return new PageImpl<>(queryData.getTotal(), bizObjectList);
    }

    @Override
    public Page<BizObjectModel> queryExportDatas(BizObjectQueryModel bizObjectQueryModel, List<BizPropertyModel> properties, Boolean mobile, List<BizQueryColumnModel> columns, String userId, Map<String, Map<String, Object>> childNumricalFormat) {
        final String schemaCode = bizObjectQueryModel.getSchemaCode();
        final String queryCode = bizObjectQueryModel.getQueryCode();
        final ClientType clientType = Objects.nonNull(bizObjectQueryModel.getClientType()) ? bizObjectQueryModel.getClientType() : ClientType.PC;
        if (StringUtils.isEmpty(schemaCode) && StringUtils.isEmpty(queryCode)) {
            throw new ServiceException(ErrCode.BIZ_QUERY_CODE_SCHEMACODE_NOT_EXIST, bizObjectQueryModel);
        }

        final BizQuery bizQuery = bizQueryService.getBySchemaCodeAndCode(schemaCode, queryCode);
        if (bizQuery == null) {
            log.debug("bizQuery is null. {}", queryCode);
            throw new ServiceException(ErrCode.BIZ_QUERY_NOT_EXIST, queryCode);
        }
        String queryId = bizQuery.getId();
        //排序信息
        List<BizQuerySort> sorts = bizQuerySortService.getListByQueryId(queryId);
        sorts = sorts.stream().filter(t -> Objects.equals(clientType, t.getClientType())).collect(Collectors.toList());
        final List<OrderImpl> orders = new ArrayList<>();
        if (CollectionUtils.isEmpty(sorts)) {
            //使用默认排序
            orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));
        } else {
            orders.addAll(getOrders(sorts));
        }
        final List<String> columnList = Lists.newArrayList();

        final Page<Map<String, Object>> queryData = bizObjectService.queryBizObjects(new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {
                return bizObjectQueryModel.getFilterExpr();
            }

            @Override
            public List<String> getDisplayFields() {
                for (BizPropertyModel propertyModel : properties) {
                    if (Objects.equals(propertyModel.getPropertyType(), BizPropertyType.ATTACHMENT)
                            || Objects.equals(propertyModel.getPropertyType(), BizPropertyType.COMMENT)
                    ) {
                        continue;

                    }
                    String code = propertyModel.getCode();
                    if (!StringUtils.isEmpty(code)) {
                        if (!columnList.contains(code)) {
                            columnList.add(code);
                        }

                    }
                }
                return columnList;
            }


            @Override
            public Pageable getPageable() {
                return bizObjectQueryModel.getPageable();
            }

            @Override
            public Sortable getSortable() {
                return orders == null ? null : new SortableImpl(orders);
            }
        });


        //转换WEB-API需要的数据
        final List<BizObjectModel> bizObjectList = Lists.newArrayListWithExpectedSize(queryData.getContent().size());
        for (Map<String, Object> map : queryData.getContent()) {
            final BizObjectModel bizObjectModel = new BizObjectModel(schemaCode, map, false);
            bizObjectList.add(bizObjectModel);
        }

        long start = System.currentTimeMillis();
        UserModel user = getUser(userId);
        String corpId = user.getCorpId();
        DepartmentModel root = departmentFacade.getCorpRootDepartment(corpId);
        String rootId = root.getId();

        machesProperty(columns, bizObjectList, mobile, schemaCode, queryCode, userId, rootId);

        long pa = System.currentTimeMillis();
        log.info("engine处理1：--{}", pa - start);
        String formCode = null;
        if (StringUtils.isEmpty(formCode)) {
            List<BizForm> bizForms = bizFormService.getListBySchemaCode(schemaCode);
            if (CollectionUtils.isNotEmpty(bizForms)) {
                formCode = bizForms.get(0).getCode();
            }
        }
        BizForm sheetModel = bizFormService.getBySchemaCodeAndFormCode(schemaCode, formCode);
        BizSchema bizSchemaModel = bizSchemaService.getBySchemaCode(schemaCode);

        for (BizObjectModel bizObject : bizObjectList) {
            for (BizQueryColumnModel column : columns) {
                Map<String, Object> format = Maps.newHashMap();
                if (column.getPropertyType() != BizPropertyType.CHILD_TABLE) {
                    continue;
                }
                Map<String, Object> data = bizObject.getData();
                List<Map<String, Object>> objectChildDatas = (List<Map<String, Object>>) data.get(column.getPropertyCode());
                List<BizQueryChildColumnModel> childColumns = column.getChildColumns();
                String subSchemaCode = column.getPropertyCode();
                if (CollectionUtils.isEmpty(objectChildDatas)) {
                    continue;
                }
                parseChildDatas(userId, objectChildDatas, childColumns, subSchemaCode, bizSchemaModel, sheetModel, childNumricalFormat, format, rootId);
            }
        }
        long end = System.currentTimeMillis();
        log.info("engine处理：--{}", end - pa);
        if (log.isTraceEnabled()) {
            log.trace("================bizObjectList={}", JSON.toJSONString(bizObjectList));
        }
        return new PageImpl<BizObjectModel>(queryData.getTotal(), bizObjectList);
    }

    @Override
    public Map<String, Map<String, Object>> queryChildNumricalFormat(BizObjectQueryModel bizObjectQueryModel, List<BizPropertyModel> properties, Boolean mobile, List<BizQueryColumnModel> columns, String userId) {
        final String schemaCode = bizObjectQueryModel.getSchemaCode();
        final String queryCode = bizObjectQueryModel.getQueryCode();
        final ClientType clientType = Objects.nonNull(bizObjectQueryModel.getClientType()) ? bizObjectQueryModel.getClientType() : ClientType.PC;
        if (StringUtils.isEmpty(schemaCode) && StringUtils.isEmpty(queryCode)) {
            throw new ServiceException(ErrCode.BIZ_QUERY_CODE_SCHEMACODE_NOT_EXIST, bizObjectQueryModel);
        }

        final BizQuery bizQuery = bizQueryService.getBySchemaCodeAndCode(schemaCode, queryCode);
        if (bizQuery == null) {
            log.debug("bizQuery is null. {}", queryCode);
            throw new ServiceException(ErrCode.BIZ_QUERY_NOT_EXIST, queryCode);
        }
        String queryId = bizQuery.getId();
        //排序信息
        List<BizQuerySort> sorts = bizQuerySortService.getListByQueryId(queryId);
        sorts = sorts.stream().filter(t -> Objects.equals(clientType, t.getClientType())).collect(Collectors.toList());
        final List<OrderImpl> orders = new ArrayList<>();
        if (CollectionUtils.isEmpty(sorts)) {
            //使用默认排序
            orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));
        } else {
            orders.addAll(getOrders(sorts));
        }
        final List<String> columnList = Lists.newArrayList();
        final Page<Map<String, Object>> queryData = bizObjectService.queryBizObjects(new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {
                return bizObjectQueryModel.getFilterExpr();
            }

            @Override
            public List<String> getDisplayFields() {
                for (BizPropertyModel propertyModel : properties) {
                    if (Objects.equals(propertyModel.getPropertyType(), BizPropertyType.ATTACHMENT)
                            || Objects.equals(propertyModel.getPropertyType(), BizPropertyType.COMMENT)
                    ) {
                        continue;

                    }
                    String code = propertyModel.getCode();
                    if (!StringUtils.isEmpty(code)) {
                        if (!columnList.contains(code)) {
                            columnList.add(code);
                        }

                    }
                }
                return columnList;
            }


            @Override
            public Pageable getPageable() {
                return bizObjectQueryModel.getPageable();
            }

            @Override
            public Sortable getSortable() {
                return orders == null ? null : new SortableImpl(orders);
            }
        });


        //转换WEB-API需要的数据
        final List<BizObjectModel> bizObjectList = Lists.newArrayListWithExpectedSize(queryData.getContent().size());
        for (Map<String, Object> map : queryData.getContent()) {
            final BizObjectModel bizObjectModel = new BizObjectModel(schemaCode, map, false);
            bizObjectList.add(bizObjectModel);
        }

        UserModel user = getUser(userId);
        String corpId = user.getCorpId();
        DepartmentModel root = departmentFacade.getCorpRootDepartment(corpId);
        String rootId = root.getId();

        machesProperty(columns, bizObjectList, mobile, schemaCode, queryCode, userId, rootId);

        String formCode = null;
        List<BizForm> bizFormHeaders = bizFormService.getListBySchemaCode(schemaCode);
        if (CollectionUtils.isNotEmpty(bizFormHeaders)) {
            formCode = bizFormHeaders.get(0).getCode();
        }
        BizForm sheetModel = bizFormService.getBySchemaCodeAndFormCode(schemaCode, formCode);
        BizSchema bizSchemaModel = bizSchemaService.getBySchemaCode(schemaCode);
        Map<String, Map<String, Object>> map = Maps.newHashMap();
        for (BizObjectModel bizObject : bizObjectList) {
            for (BizQueryColumnModel column : columns) {

                if (column.getPropertyType() != BizPropertyType.CHILD_TABLE) {
                    continue;
                }
                Map<String, Object> data = bizObject.getData();
                List<Map<String, Object>> objectChildDatas = (List<Map<String, Object>>) data.get(column.getPropertyCode());
                List<BizQueryChildColumnModel> childColumns = column.getChildColumns();
                String subSchemaCode = column.getPropertyCode();
                if (CollectionUtils.isEmpty(objectChildDatas)) {
                    continue;
                }
                map.putAll(getChildNumricalFormat(objectChildDatas, childColumns, subSchemaCode, bizSchemaModel, sheetModel));
            }
        }
        return map;
    }

    protected Map<String, Map<String, Object>> getChildNumricalFormat(List<Map<String, Object>> maps, List<BizQueryChildColumnModel> childColumns, String subSchemaCode,
                                                                      BizSchema bizSchemaModel, BizForm sheetModel) {
        Map<String, Map<String, Object>> childNumricalFormat = Maps.newHashMap();
        Map<String, Object> format = Maps.newHashMap();
        List<BizProperty> bizProperties = bizPropertyService.getListBySchemaCode(subSchemaCode, true);
        List<BizProperty> collect = bizProperties.stream().filter(t -> t.getPropertyType().equals(BizPropertyType.NUMERICAL)).collect(Collectors.toList());
        List<BizProperty> collectAddress = bizProperties.stream().filter(t -> t.getPropertyType().equals(BizPropertyType.ADDRESS)).collect(Collectors.toList());
        List<BizProperty> workSheets = bizProperties.stream().filter(t -> t.getPropertyType().equals(BizPropertyType.WORK_SHEET)).collect(Collectors.toList());
        List<BizProperty> multWorkSheets = bizProperties.stream().filter(t -> t.getPropertyType().equals(BizPropertyType.MULT_WORK_SHEET)).collect(Collectors.toList());
        workSheets.addAll(multWorkSheets);

        Map<String, String> mapTemplate = new HashMap<>();

        //数值或者地址
        if (CollectionUtils.isNotEmpty(collect) || CollectionUtils.isNotEmpty(collectAddress)) {
            Map<String, String> mapTemplateAddress = Maps.newHashMapWithExpectedSize(collectAddress.size());
            List<Map> childColumnList = getChildColumns(sheetModel.getPublishedAttributesJson(), subSchemaCode);
            for (BizProperty bizPropertyModel : collect) {
                if (CollectionUtils.isNotEmpty(childColumnList)) {
                    for (Map childColumn : childColumnList) {
                        if (childColumn.get("key").toString().equals(bizPropertyModel.getCode())) {
                            Map map2 = JSON.parseObject(childColumn.get("options").toString(), Map.class);
                            Object format1 = map2.get("format");
                            if (Objects.isNull(format1)) {
                                continue;
                            }
                            mapTemplate.put(bizPropertyModel.getCode(), format1.toString());
                        }
                    }
                }
            }
            for (BizProperty bizPropertyModel : collectAddress) {
                for (BizQueryChildColumnModel childColumn : childColumns) {
                    if (CollectionUtils.isNotEmpty(childColumnList)) {
                        if (childColumn.getPropertyCode().equals(bizPropertyModel.getCode())) {
                            mapTemplateAddress.put(bizPropertyModel.getCode(), childColumn.getPropertyCode());
                        }
                    }
                }
            }
        }

        if (CollectionUtils.isNotEmpty(childColumns)) {
            for (BizQueryChildColumnModel columnModel : childColumns) {
                for (Map<String, Object> data : maps) {
                    if (columnModel.getPropertyType() == BizPropertyType.ADDRESS) {
                        String json = null;
                        if (data.get(columnModel.getPropertyCode()) != null) {
                            json = data.get(columnModel.getPropertyCode()).toString();
                        }
                        if ("{}".equals(json)) {
                            json = null;
                            data.put(columnModel.getPropertyCode(), null);
                        }
                        if (StringUtils.isNotEmpty(json)) {
                            Map map = JSONObject.parseObject(json, Map.class);
                            String name = "";
                            if (map.get("provinceName") != null) {
                                name = name + map.get("provinceName");
                            }
                            if (map.get("cityName") != null) {
                                name = name + map.get("cityName");
                            }
                            if (map.get("districtName") != null) {
                                name = name + map.get("districtName");
                            }
                            if (map.get("address") != null) {
                                name = name + map.get("address");
                            }
                            data.put(columnModel.getPropertyCode(), name);
                        }
                    }
                    //关联表单
                    if (columnModel.getPropertyType() == BizPropertyType.WORK_SHEET || columnModel.getPropertyType() == BizPropertyType.MULT_WORK_SHEET) {

                        if (data.get(columnModel.getPropertyCode()) != null) {
                            String properCode = columnModel.getPropertyCode();
                            Object o = data.get(properCode);
                            List<BizProperty> workSheet = workSheets.stream().filter(property -> Objects.equals(property.getCode(), columnModel.getPropertyCode())).collect(Collectors.toList());
                            if (CollectionUtils.isEmpty(workSheet)) {
                                data.put(properCode, "");
                                continue;
                            }
                            BizProperty bizPropertyModel = workSheet.get(0);
                            String relativePropertyCode = bizPropertyModel.getRelativePropertyCode();
                            if (StringUtils.isEmpty(relativePropertyCode)) {
                                relativePropertyCode = "name";
                            }
                            Map<String, Object> workSheetData = (Map<String, Object>) o;
                            String value = Objects.isNull(workSheetData.get(relativePropertyCode)) ? "" : workSheetData.get(relativePropertyCode).toString();
                            data.put(properCode, value);

                        }

                    }

                    //数值类型
                    if (columnModel.getPropertyType() == BizPropertyType.NUMERICAL) {
                        if (data.get(columnModel.getPropertyCode()) == null) {
                            continue;
                        }
//                        DecimalFormat df = null;
                        String code = columnModel.getPropertyCode();
                        String displatFormat = mapTemplate.get(code);
                        if (StringUtils.isEmpty(displatFormat)) {
                            displatFormat = "null";
                            format.put(columnModel.getPropertyCode(), displatFormat);
                            childNumricalFormat.put(subSchemaCode, format);
                            continue;
                        }
                        format.put(columnModel.getPropertyCode(), displatFormat);
                        childNumricalFormat.put(subSchemaCode, format);
                    }

                }

            }
        }
        return childNumricalFormat;

    }


    /**
     * 处理子表数据项导出的格式
     *
     * @param childColumns  展示字段
     * @param maps          业务数据对象
     * @param subSchemaCode
     * @return
     */

    private void parseChildDatas(String userId, List<Map<String, Object>> maps, List<BizQueryChildColumnModel> childColumns, String subSchemaCode,
                                 BizSchema bizSchemaModel, BizForm sheetModel, Map<String, Map<String, Object>> childNumricalFormat, Map<String, Object> format, String rootId) {
        List<BizProperty> bizProperties = bizPropertyService.getListBySchemaCode(subSchemaCode, true);
        List<BizProperty> collect = bizProperties.stream().filter(t -> t.getPropertyType() == BizPropertyType.NUMERICAL).collect(Collectors.toList());
        List<BizProperty> collectAddress = bizProperties.stream().filter(t -> t.getPropertyType() == BizPropertyType.ADDRESS).collect(Collectors.toList());
        List<BizProperty> workSheets = bizProperties.stream().filter(t -> t.getPropertyType() == BizPropertyType.WORK_SHEET).collect(Collectors.toList());
        List<BizProperty> multWorkSheets = bizProperties.stream().filter(t -> t.getPropertyType() == BizPropertyType.MULT_WORK_SHEET).collect(Collectors.toList());
        workSheets.addAll(multWorkSheets);
        Map<String, String> mapTemplate = new HashMap<>();

        //数值或者地址
        if (CollectionUtils.isNotEmpty(collect) || CollectionUtils.isNotEmpty(collectAddress)) {
            List<Map> childColumnList = getChildColumns(sheetModel.getPublishedAttributesJson(), subSchemaCode);
            for (BizProperty bizPropertyModel : collect) {
                if (CollectionUtils.isNotEmpty(childColumnList)) {
                    for (Map childColumn : childColumnList) {
                        if (childColumn.get("key").toString().equals(bizPropertyModel.getCode())) {
                            Map map2 = JSON.parseObject(childColumn.get("options").toString(), Map.class);
                            Object format1 = map2.get("format");
                            if (Objects.isNull(format1)) {
                                continue;
                            }
                            mapTemplate.put(bizPropertyModel.getCode(), format1.toString());
                        }
                    }
                }
            }
            Map<String, String> mapTemplateAddress = Maps.newHashMapWithExpectedSize(collectAddress.size());
            for (BizProperty bizPropertyModel : collectAddress) {
                for (BizQueryChildColumnModel childColumn : childColumns) {
                    if (CollectionUtils.isNotEmpty(childColumnList)) {
                        if (childColumn.getPropertyCode().equals(bizPropertyModel.getCode())) {
                            mapTemplateAddress.put(bizPropertyModel.getCode(), childColumn.getPropertyCode());
                        }
                    }
                }
            }
        }

        if (CollectionUtils.isNotEmpty(childColumns)) {

            for (BizQueryChildColumnModel columnModel : childColumns) {
                for (Map<String, Object> data : maps) {
                    if (columnModel.getPropertyType().equals(BizPropertyType.ADDRESS)) {
                        String json = null;
                        if (data.get(columnModel.getPropertyCode()) != null) {
                            json = data.get(columnModel.getPropertyCode()).toString();
                        }
                        if ("{}".equals(json)) {
                            json = null;
                            data.put(columnModel.getPropertyCode(), null);
                        }
                        if (StringUtils.isNotEmpty(json)) {
                            Map map = JSONObject.parseObject(json, Map.class);
                            String name = "";
                            if (map.get("provinceName") != null) {
                                name = name + map.get("provinceName");
                            }
                            if (map.get("cityName") != null) {
                                name = name + map.get("cityName");
                            }
                            if (map.get("districtName") != null) {
                                name = name + map.get("districtName");
                            }
                            if (map.get("address") != null) {
                                name = name + map.get("address");
                            }
                            data.put(columnModel.getPropertyCode(), name);
                        }
                    }
                    //关联表单
                    if (columnModel.getPropertyType() == BizPropertyType.WORK_SHEET || columnModel.getPropertyType() == BizPropertyType.MULT_WORK_SHEET) {

                        if (data.get(columnModel.getPropertyCode()) != null) {
                            String properCode = columnModel.getPropertyCode();
                            Object o = data.get(properCode);
                            List<BizProperty> workSheet = workSheets.stream().filter(property -> Objects.equals(property.getCode(), columnModel.getPropertyCode())).collect(Collectors.toList());
                            if (CollectionUtils.isEmpty(workSheet)) {
                                data.put(properCode, "");
                                continue;
                            }
                            BizProperty bizPropertyModel = workSheet.get(0);
                            String relativePropertyCode = bizPropertyModel.getRelativePropertyCode();
                            if (StringUtils.isEmpty(relativePropertyCode)) {
                                relativePropertyCode = "name";
                            }
                            Map<String, Object> workSheetData = (Map<String, Object>) o;
                            if (workSheetData.get("propertyType") == BizPropertyType.SELECTION) {
                                List<SelectionValue> selectionValues = (List<SelectionValue>) workSheetData.get(relativePropertyCode);
                                data.put(properCode, getUserNameList(selectionValues, rootId));
                            } else if (workSheetData.get("propertyType") == BizPropertyType.ADDRESS) {
                                String json = null;
                                if (workSheetData.get(relativePropertyCode) == null) {
                                    data.put(properCode, null);
                                    continue;
                                }
                                json = workSheetData.get(relativePropertyCode).toString();
                                if ("{}".equals(json)) {
                                    json = null;
                                    data.put(properCode, null);
                                }
                                if (StringUtils.isNotEmpty(json)) {
                                    Map map = JSONObject.parseObject(json, Map.class);
                                    String name = "";
                                    if (map.get("provinceName") != null) {
                                        name = name + map.get("provinceName");
                                    }
                                    if (map.get("cityName") != null) {
                                        name = name + map.get("cityName");
                                    }
                                    if (map.get("districtName") != null) {
                                        name = name + map.get("districtName");
                                    }
                                    if (map.get("address") != null) {
                                        name = name + map.get("address");
                                    }
                                    data.put(properCode, name);
                                }
                            } else if (workSheetData.get("propertyType") == BizPropertyType.DATE) {
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                data.put(properCode, Objects.isNull(workSheetData.get(relativePropertyCode)) ? "" : simpleDateFormat.format(workSheetData.get(relativePropertyCode)));
                            } else {
                                String value = Objects.isNull(workSheetData.get(relativePropertyCode)) ? "" : workSheetData.get(relativePropertyCode).toString();
                                data.put(properCode, value);
                            }

                        }

                    }


                    //数值类型
                    if (columnModel.getPropertyType() == BizPropertyType.NUMERICAL) {
                        if (data.get(columnModel.getPropertyCode()) == null) {
                            continue;
                        }
                        DecimalFormat df = null;
                        String code = columnModel.getPropertyCode();
                        String displatFormat = mapTemplate.get(code);
                        if (StringUtils.isEmpty(displatFormat)) {
                            displatFormat = "null";
                            format.put(columnModel.getPropertyCode(), displatFormat);
                            childNumricalFormat.put(subSchemaCode, format);
                            continue;
                        }
//                    if (StringUtils.isEmpty(mapTemplate.get(columnModel.getPropertyCode()))){
//                        displatFormat = "null";
//                        format.put(columnModel.getPropertyCode(),displatFormat);
//                        childNumricalFormat.put(subSchemaCode,format);
//                        continue;
//                    }
                        switch (mapTemplate.get(columnModel.getPropertyCode())) {
                            case "integer":
                                df = new DecimalFormat("##0");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "tenths":
                                df = new DecimalFormat("###,##0.0");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "percentile":
                                df = new DecimalFormat("###,##0.00");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "Millimeter":
                                df = new DecimalFormat("###,##0.000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "tenThousand":
                                df = new DecimalFormat("###,##0.0000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "hundredThousand":
                                df = new DecimalFormat("###,##0.00000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "millionDecimals":
                                df = new DecimalFormat("###,##0.000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "tenMillionDecimals":
                                df = new DecimalFormat("###,##0.0000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "billionDecimals":
                                df = new DecimalFormat("###,##0.00000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio":
                                df = new DecimalFormat("###,##0%");
                                BigDecimal ratioResult = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioResult = ratioResult.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioResult));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.tenths":
                                df = new DecimalFormat("###,##0.0" + "%");
                                BigDecimal ratioTenths = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioTenths = ratioTenths.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioTenths));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.percentile":
                                df = new DecimalFormat("###,##0.00" + "%");
                                BigDecimal ratioPercentile = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile = ratioPercentile.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.Millimeter":
                                df = new DecimalFormat("###,##0.000" + "%");
                                BigDecimal ratioPercentile1 = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile1 = ratioPercentile1.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile1));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.tenThousand":
                                df = new DecimalFormat("###,##0.0000" + "%");
                                BigDecimal ratioPercentile2 = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile2 = ratioPercentile2.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile2));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.hundredThousand":
                                df = new DecimalFormat("###,##0.00000" + "%");
                                BigDecimal ratioPercentile3 = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile3 = ratioPercentile3.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile3));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.millionDecimals":
                                df = new DecimalFormat("###,##0.000000" + "%");
                                BigDecimal ratioPercentile4 = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile4 = ratioPercentile4.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile4));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.tenMillionDecimals":
                                df = new DecimalFormat("###,##0.0000000" + "%");
                                BigDecimal ratioPercentile5 = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile5 = ratioPercentile5.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile5));
                                childNumricalFormat.put(code, data);
                                break;
                            case "ratio.billionDecimals":
                                df = new DecimalFormat("###,##0.00000000" + "%");
                                BigDecimal ratioPercentile6 = (BigDecimal) data.get(columnModel.getPropertyCode());
                                ratioPercentile6 = ratioPercentile6.divide(new BigDecimal("100"));
                                data.put(columnModel.getPropertyCode(), df.format(ratioPercentile6));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.percentile":
                                df = new DecimalFormat("¥#,##0.00");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.Millimeter":
                                df = new DecimalFormat("¥#,##0.000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.tenThousand":
                                df = new DecimalFormat("¥#,##0.0000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.hundredThousand":
                                df = new DecimalFormat("¥#,##0.00000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.millionDecimals":
                                df = new DecimalFormat("¥#,##0.000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.tenMillionDecimals":
                                df = new DecimalFormat("¥#,##0.0000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "RMB.billionDecimals":
                                df = new DecimalFormat("¥#,##0.00000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.percentile":
                                df = new DecimalFormat("$#,##0.00");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.Millimeter":
                                df = new DecimalFormat("$#,##0.000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.tenThousand":
                                df = new DecimalFormat("$#,##0.0000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.hundredThousand":
                                df = new DecimalFormat("$#,##0.00000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.millionDecimals":
                                df = new DecimalFormat("$#,##0.000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.tenMillionDecimals":
                                df = new DecimalFormat("$#,##0.0000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "dollar.billionDecimals":
                                df = new DecimalFormat("$#,##0.00000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.percentile":
                                df = new DecimalFormat("€#,##0.00");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.Millimeter":
                                df = new DecimalFormat("€#,##0.000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.tenThousand":
                                df = new DecimalFormat("€#,##0.0000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.hundredThousand":
                                df = new DecimalFormat("€#,##0.00000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.millionDecimals":
                                df = new DecimalFormat("€#,##0.000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.tenMillionDecimals":
                                df = new DecimalFormat("€#,##0.0000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "euro.billionDecimals":
                                df = new DecimalFormat("€#,##0.00000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.percentile":
                                df = new DecimalFormat("HK$#,##0.00");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.Millimeter":
                                df = new DecimalFormat("HK$#,##0.000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.tenThousand":
                                df = new DecimalFormat("HK$#,##0.0000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.hundredThousand":
                                df = new DecimalFormat("HK$#,##0.00000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.millionDecimals":
                                df = new DecimalFormat("HK$#,##0.000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.tenMillionDecimals":
                                df = new DecimalFormat("HK$#,##0.0000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            case "HK.billionDecimals":
                                df = new DecimalFormat("HK$#,##0.00000000");
                                data.put(columnModel.getPropertyCode(), df.format(data.get(columnModel.getPropertyCode())));
                                childNumricalFormat.put(code, data);
                                break;
                            default:
                                break;
                        }
                    }
                }
                if (BizPropertyType.selectionTypes.contains(columnModel.getPropertyType())) {
                    childParseSpecialPropertiess(maps, true, columnModel, rootId);
                }
                if (columnModel.getPropertyType() == BizPropertyType.LOGICAL) {
                    childParselogicalPropertiess(maps, true, columnModel);
                }

            }
        }

    }

    /**
     * 处理PC端子表逻辑控件展示
     *
     * @param datas       分页数据
     * @param columnModel 子表的选人控件字段
     * @param isExport    是否导出
     */
    private void childParselogicalPropertiess(List<Map<String, Object>> datas, Boolean isExport, BizQueryChildColumnModel columnModel) {

        if (CollectionUtils.isNotEmpty(datas)) {
            for (int i = 0; i < datas.size(); i++) {
                Map<String, Object> data = datas.get(i);
                String propertyCode = columnModel.getPropertyCode();
                Object logical = data.get(propertyCode);
                if (logical == null) {
                    String logic = "null";
                    logical = logic;
                }
                if (StringUtils.isEmpty(logical.toString())) {
                    data.put(columnModel.getPropertyCode(), "否");
                } else {
                    switch (logical.toString()) {
                        case "1":
                            data.put(columnModel.getPropertyCode(), "是");
                            break;
                        case "0":
                            data.put(columnModel.getPropertyCode(), "否");
                            break;
                        case "true":
                            data.put(columnModel.getPropertyCode(), "是");
                            break;
                        case "false":
                            data.put(columnModel.getPropertyCode(), "否");
                            break;
                        default:
                            data.put(columnModel.getPropertyCode(), "否");
                            break;
                    }
                }
            }
        }
    }

    /**
     * 处理PC端子表选人控件展示
     *
     * @param datas 分页数据
     */
    private void childParseSpecialPropertiess(List<Map<String, Object>> datas, Boolean isExport, BizQueryChildColumnModel columnModel, String rootId) {
        if (CollectionUtils.isNotEmpty(datas)) {
            for (int i = 0; i < datas.size(); i++) {
                Map<String, Object> data = datas.get(i);
                Object o = data.get(columnModel.getPropertyCode());
                if (o instanceof String) {
                    data.put(columnModel.getPropertyCode(), o);
                } else {
                    List<SelectionValue> selectionValues = (List<SelectionValue>) data.get(columnModel.getPropertyCode());
                    if (CollectionUtils.isNotEmpty(selectionValues)) {
                        Object name = getUserNameList(selectionValues, rootId);
                        if (Objects.nonNull(name)) {
                            if (Objects.nonNull(name)) {
                                data.put(columnModel.getPropertyCode(), name);
                            } else {
                                data.put(columnModel.getPropertyCode(), "");
                            }
                        } else {
                            data.put(columnModel.getPropertyCode(), "");
                        }
                    } else {
                        data.put(columnModel.getPropertyCode(), "");
                    }
                }
            }
        }
    }

    /**
     * 解析表单配置信息
     *
     * @param jsonString
     * @param subSchemaCode
     * @return
     */
    protected List<Map> getChildColumns(String jsonString, String subSchemaCode) {
        if (StringUtils.isEmpty(jsonString)) {
            return null;
        }
        Map map = JSON.parseObject(jsonString, Map.class);
        Object object = map.get(subSchemaCode);

        if (null != object) {
            Object columns = ((JSONObject) object).get("columns");
            if (columns instanceof JSONArray) {
                return JSONObject.parseArray(JSON.toJSONString(columns), Map.class);
            } else if (columns instanceof List) {
                return (List) columns;
            }
        }

        return null;
    }

    /**
     * 处理主表数据项导出的格式
     *
     * @param columns 展示字段
     * @param data    业务数据对象
     * @return
     */
    protected void machesProperty(List<BizQueryColumnModel> columns, List<BizObjectModel> data, Boolean mobile, String schemaCode, String queryCode, String userId, String rootId) {

        if (CollectionUtils.isEmpty(data)) {
            return;
        }
        if (CollectionUtils.isEmpty(columns)) {
            return;
        }
        List<BizProperty> bizProperties = bizPropertyService.getListBySchemaCode(schemaCode, true);
        if (CollectionUtils.isNotEmpty(data)) {
            parseAddressAndReferences(data, columns, true, queryCode, schemaCode, userId, bizProperties, rootId);
            if (!mobile) {
                //处理PC端选人
                parseSpecialPropertiess(data, true, rootId);
            } else {
                //处理移动端用户图像
                disposeUserInfos(data);
            }
        }

    }

    /**
     * 处理PC端选人控件展示
     *
     * @param data 分页数据
     */
    private void parseSpecialPropertiess(List<BizObjectModel> data, Boolean isExport, String rootId) {
        //获选人数据项
        BizObjectModel objectModel = data.get(0);
        BizSchema bizSchema = bizSchemaService.getBySchemaCode(objectModel.getSchemaCode());
        if (isExport) {
            List<String> selectCodes = getPropertyCodeList(objectModel, BizPropertyType.selectionTypes);
            if (CollectionUtils.isEmpty(selectCodes)) {
                return;
            }
//            log.debug("需要处理的选人数据项为{}", JSON.toJSONString(selectCodes));
            Set<String> dataCodes = null;
            for (String selectCode : selectCodes) {
                for (BizObjectModel bizObject : data) {
                    if (CollectionUtils.isEmpty(dataCodes)) {
                        dataCodes = bizObject.getData().keySet();
//                        log.debug("需要展示的数据项为{}", JSON.toJSONString(dataCodes));
                    }
                    if (!dataCodes.contains(selectCode)) {
//                        log.debug("不需要展示的选人数据项为{}", selectCode);
                        break;
                    }
                    if (bizObject.get(selectCode) == null) {
                        continue;
                    }
                    List<SelectionValue> selectionValues = (List<SelectionValue>) bizObject.get(selectCode);
                    bizObject.put(selectCode, getUserNameList(selectionValues, rootId));
                }
            }
            //处理单据状态
            if (data.get(0).getData().keySet().contains(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
                for (BizObjectModel bizObjectModel : data) {
                    bizObjectModel.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), parseSequenceStatus(bizObjectModel));
                }
            }
            List<BizProperty> bizProperties = bizPropertyService.getListBySchemaCode(objectModel.getSchemaCode(), true);
            //获取逻辑型
            List<BizProperty> logicalModels = bizProperties.stream().filter(t -> t.getPropertyType() == BizPropertyType.LOGICAL).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(logicalModels)) {
                List<String> logicals = getPropertyCodes(logicalModels);
                Set<String> logicalDataCodes = null;
                for (String logical : logicals) {
                    for (BizObjectModel bizObjectModel : data) {
                        if (CollectionUtils.isEmpty(logicalDataCodes)) {
                            logicalDataCodes = bizObjectModel.getData().keySet();
                        }
                        if (!logicalDataCodes.contains(logical)) {
                            break;
                        }
                        if (bizObjectModel.get(logical) == null) {
                            continue;
                        }
                        bizObjectModel.put(logical, disposeLogics(bizObjectModel.getString(logical)));
                    }

                }
            }
        }

    }

    /**
     * 处理审批意见
     *
     * @param logic
     * @return
     */
    public Object disposeLogics(String logic) {
        switch (logic) {
            case "1":
                return "是";
            case "0":
                return "否";
            case "true":
                return "是";
            case "false":
                return "否";
            default:
                return "否";
        }

    }

    /**
     * 处理单据状态
     *
     * @param bizObjectModel
     * @return
     */
    private Object parseSequenceStatus(BizObjectModel bizObjectModel) {
        switch (bizObjectModel.get(DefaultPropertyType.SEQUENCE_STATUS.getCode()).toString()) {
            case "DRAFT":
                return SequenceStatus.DRAFT.getName();
            case "PROCESSING":
                return SequenceStatus.PROCESSING.getName();
            case "CANCELLED":
                return SequenceStatus.CANCELLED.getName();
            case "COMPLETED":
                return SequenceStatus.COMPLETED.getName();
            case "CANCELED":
                return SequenceStatus.CANCELED.getName();

            default:
                return null;
        }
    }

    /**
     * 从列表数据中获取到用户名
     *
     * @return Object
     */
    public Object getUserNameList(List<SelectionValue> selectionValues, String rootId) {
        if (selectionValues == null) {
            return "";
        }
        List<SelectionValue> unitType = selectionValues.stream().filter(selectionValue -> selectionValue != null && Objects.equals(selectionValue.getType(), UnitType.DEPARTMENT)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(unitType)) {
            return selectionValues.stream().filter(selectionValue -> selectionValue != null && StringUtils.isNotEmpty(selectionValue.getName())).map(SelectionValue::getName).collect(Collectors.joining(";"));
        }
        Map<String, String> deptMap = selectionValues.stream().filter(selectionValue -> ((selectionValue != null) && StringUtils.isNotEmpty(selectionValue.getName()) && StringUtils.isNotEmpty(selectionValue.getId()) && Objects.equals(selectionValue.getType(), UnitType.DEPARTMENT))).collect(Collectors.toMap(SelectionValue::getId, SelectionValue::getName));
        Set<String> deptIds = deptMap.keySet();
        List<String> nameList = Lists.newArrayList();
        for (String id : deptIds) {
            Map<String, String> pathMap = getParentDepartNamesById(id, rootId);
            String path = pathMap.get(id);
            nameList.add(path);
        }
        List<String> userNameList = selectionValues.stream().filter(selectionValue -> ((selectionValue != null) && StringUtils.isNotEmpty(selectionValue.getName()) && StringUtils.isNotEmpty(selectionValue.getId()) && Objects.equals(selectionValue.getType(), UnitType.USER))).map(SelectionValue::getName).collect(Collectors.toList());
        nameList.addAll(userNameList);
        if (CollectionUtils.isEmpty(nameList)) {
            return "";
        }
        if (nameList.get(0) == null) {
            return "";
        }
        return Joiner.on(";").skipNulls().join(nameList);
    }

    public Map<String, String> getParentDepartNamesById(String id, String rootId) {
        DepartmentModel department = departmentFacade.get(id);
        Map<String, String> map = null;
        if (department != null) {
            map = new HashMap<>();
            boolean equals = Objects.equals(id, rootId);

            String path = null;
            if (equals) {
                path = department.getName();
                map.put(department.getId(), path);
            } else {
                path = departmentFacade.getDeptPath(department.getId());
                if (StringUtils.isNotEmpty(path)) {
                    path = path + "/" + department.getName();
                    map.put(department.getId(), path);
                } else {
                    map.put(department.getId(), department.getName());
                }
            }
        }
        return map;
    }

    /*
     *
     *
     * */
    private List<String> getPropertyCodeList(BizObjectModel objectModel, Set<BizPropertyType> propertyTypes) {
        List<BizProperty> bizProperties = bizPropertyService.getListBySchemaCode(objectModel.getSchemaCode(), true);
        if (CollectionUtils.isEmpty(bizProperties)) {
            return Collections.emptyList();
        }
        List<BizProperty> bizPropertyModels = bizProperties.stream().filter(t -> propertyTypes.contains(t.getPropertyType())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(bizPropertyModels)) {
            return getPropertyCodes(bizPropertyModels);
        }
        return Collections.emptyList();
    }

    /**
     * 设置用户显示图像
     *
     * @param data 分页数据
     */
    private void disposeUserInfos(List<BizObjectModel> data) {
        if (CollectionUtils.isEmpty(data)) {
            return;
        }
        for (BizObjectModel bizObject : data) {
            List<SelectionValue> selectionValues = (List<SelectionValue>) bizObject.get(DefaultPropertyType.CREATER.getCode());
            if (CollectionUtils.isNotEmpty(selectionValues)) {
                bizObject.put("imgUrl", selectionValues.get(0).getImgUrl());
                bizObject.put("originator", selectionValues.get(0).getName());
            }
        }
    }

    /**
     * 处理位置、数值、日期、关联表单、关联表单多选数据
     *
     * @param data
     */
    protected void parseAddressAndReferences(List<BizObjectModel> data, List<BizQueryColumnModel> columns, Boolean isExport, String queryCode, String schemaCode, String userId, List<BizProperty> propertyModels, String rootId) {
        if (CollectionUtils.isEmpty(columns) || CollectionUtils.isEmpty(data)) {
            return;
        }
        if (isExport) {
            //获取模板信息
            BizQueryModel bizQuery = bizQueryService.getBizQueryModel(schemaCode, queryCode, ClientType.PC);
            columns = columns.stream().filter(t -> t.getPropertyType().equals(BizPropertyType.ADDRESS) || t.getPropertyType().equals(BizPropertyType.WORK_SHEET) || t.getPropertyType().equals(BizPropertyType.MULT_WORK_SHEET) || t.getPropertyType().equals(BizPropertyType.NUMERICAL) || t.getPropertyType().equals(BizPropertyType.DATE)).collect(Collectors.toList());
            for (BizQueryColumnModel columnModel : columns) {
                for (BizObjectModel bizObjectModel : data) {
                    if (columnModel.getPropertyType().equals(BizPropertyType.ADDRESS)) {
                        parseAddress(bizObjectModel, columnModel);
                    }
                    if ((columnModel.getPropertyType().equals(BizPropertyType.WORK_SHEET) || columnModel.getPropertyType().equals(BizPropertyType.MULT_WORK_SHEET)) && !("业务对象ID".equals(columnModel.getName()))) {
                        if (bizObjectModel.get(columnModel.getPropertyCode()) == null) {
                            continue;
                        }
                        if (bizObjectModel.getData().get(columnModel.getPropertyCode()) != null) {
                            String code = columnModel.getPropertyCode();
                            Object o1 = bizObjectModel.getData().get(code);
                            List<BizProperty> collect = propertyModels.stream().filter(property -> Objects.equals(property.getCode(), columnModel.getPropertyCode())).collect(Collectors.toList());
                            if (CollectionUtils.isEmpty(collect)) {
                                bizObjectModel.put(code, "");
                                continue;
                            }
                            BizProperty bizProperty = collect.get(0);
                            String relativePropertyCode = bizProperty.getRelativePropertyCode();
                            if (StringUtils.isEmpty(relativePropertyCode)) {
                                relativePropertyCode = "name";
                            }
                            Map<String, Object> workSheet = (Map<String, Object>) o1;
                            if (workSheet.get("propertyType") == BizPropertyType.SELECTION) {
                                List<SelectionValue> selectionValues = (List<SelectionValue>) workSheet.get(relativePropertyCode);
                                bizObjectModel.put(code, getUserNameList(selectionValues, rootId));
                            } else if (workSheet.get("propertyType") == BizPropertyType.ADDRESS) {
                                String json = null;
                                if (workSheet.get(relativePropertyCode) == null) {
                                    bizObjectModel.put(code, null);
                                    continue;
                                }
                                json = workSheet.get(relativePropertyCode).toString();
                                if ("{}".equals(json)) {
                                    json = null;
                                    bizObjectModel.put(code, null);
                                }
                                if (StringUtils.isNotEmpty(json)) {
                                    Map map = JSONObject.parseObject(json, Map.class);
                                    String name = "";
                                    if (map.get("provinceName") != null) {
                                        name = name + map.get("provinceName");
                                    }
                                    if (map.get("cityName") != null) {
                                        name = name + map.get("cityName");
                                    }
                                    if (map.get("districtName") != null) {
                                        name = name + map.get("districtName");
                                    }
                                    if (map.get("address") != null) {
                                        name = name + map.get("address");
                                    }
                                    bizObjectModel.put(code, name);
                                }
                            } else if (workSheet.get("propertyType") == BizPropertyType.DATE) {
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                bizObjectModel.put(code, Objects.isNull(workSheet.get(relativePropertyCode)) ? "" : simpleDateFormat.format(workSheet.get(relativePropertyCode)));
                            } else {
                                String value = Objects.isNull(workSheet.get(relativePropertyCode)) ? "" : workSheet.get(relativePropertyCode).toString();
                                bizObjectModel.put(code, value);
                            }

                        }
                    }
                    if (columnModel.getPropertyType().equals(BizPropertyType.NUMERICAL)) {
                        parseNumber(bizObjectModel, columnModel, bizQuery);
                    }
                    if (columnModel.getPropertyType().equals(BizPropertyType.DATE)) {
                        parseDate(bizObjectModel, columnModel, bizQuery);
                    }
                }
            }
        }
    }


    //处理地址数据
    private void parseAddress(BizObjectModel bizObjectModel, BizQueryColumnModel columnModel) {
        String json = null;
        if (bizObjectModel.get(columnModel.getPropertyCode()) != null) {
            json = bizObjectModel.get(columnModel.getPropertyCode()).toString();
        }
        if ("{}".equals(json)) {
            json = null;
            bizObjectModel.put(columnModel.getPropertyCode(), null);
        }
        if (StringUtils.isNotEmpty(json)) {
            Map map = JSONObject.parseObject(json, Map.class);
            String name = "";
            if (map.get("provinceName") != null) {
                name = name + map.get("provinceName");
            }
            if (map.get("cityName") != null) {
                name = name + map.get("cityName");
            }
            if (map.get("districtName") != null) {
                name = name + map.get("districtName");
            }
            if (map.get("address") != null) {
                name = name + map.get("address");
            }
            bizObjectModel.put(columnModel.getPropertyCode(), name);
        }
    }

    //处理数值数据
    private void parseNumber(BizObjectModel bizObjectModel, BizQueryColumnModel columnModel, BizQueryModel bizQuery) {

        List<BizQueryColumnModel> queryColumns = bizQuery.getQueryColumns();
        BizQueryColumnModel bizQueryColumnMode = null;
        for (BizQueryColumnModel bizQueryColumnModel : queryColumns) {
            boolean exits = bizQueryColumnModel.getPropertyType().equals(BizPropertyType.NUMERICAL);
            if (exits && Objects.equals(columnModel.getPropertyCode(), bizQueryColumnModel.getPropertyCode())) {
                bizQueryColumnMode = bizQueryColumnModel;
            }
        }
        if (bizObjectModel.getData().get(columnModel.getPropertyCode()) == null) {
            return;
        }
        DecimalFormat df = null;
        if (bizQueryColumnMode == null) {
            df = new DecimalFormat("##0.######");
            bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
            return;
        }
        Integer displayFormat = bizQueryColumnMode.getDisplayFormat();
        if (displayFormat == null) {
            displayFormat = 0;
        }
        switch (displayFormat) {
            case 1:
                df = new DecimalFormat("##0");
                df.setRoundingMode(RoundingMode.DOWN);
                Object value = bizObjectModel.getData().get(columnModel.getPropertyCode());
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(value));
                break;
            case 2:
                df = new DecimalFormat("###,##0.0");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 3:
                df = new DecimalFormat("###,##0.00");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 11:
                df = new DecimalFormat("###,##0.000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 12:
                df = new DecimalFormat("###,##0.0000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            //百分符号
            case 4:
                df = new DecimalFormat("##0");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioResult = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                ratioResult = ratioResult.divide(new BigDecimal("100"));
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioResult));
                break;
            case 5:
                df = new DecimalFormat("###,##0.0");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioTenths = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                ratioTenths = ratioTenths.divide(new BigDecimal("100"));
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioTenths));
                break;
            case 6:
                df = new DecimalFormat("###,##0.00");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                ratioPercentile = ratioPercentile.divide(new BigDecimal("100"));
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile));
                break;
            case 13:
                df = new DecimalFormat("###,##0.000");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile1 = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                ratioPercentile1 = ratioPercentile1.divide(new BigDecimal("100"));
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile1));
                break;
            case 14:
                df = new DecimalFormat("###,##0.0000");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile2 = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                ratioPercentile2 = ratioPercentile2.divide(new BigDecimal("100"));
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile2));
                break;
            case 27:
                df = new DecimalFormat("###,##0.00000");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile3 = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile3));
                break;
            case 28:
                df = new DecimalFormat("###,##0.0000000");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile4 = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile4));
                break;
            case 29:
                df = new DecimalFormat("###,##0.00000000");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile5 = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile5));
                break;
            case 30:
                df = new DecimalFormat("###,##0.000000000");
                df.setRoundingMode(RoundingMode.DOWN);
                BigDecimal ratioPercentile6 = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile6));
                break;
            case 7:
                df = new DecimalFormat("¥#,##0.00");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 15:
                df = new DecimalFormat("¥#,##0.000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 16:
                df = new DecimalFormat("¥#,##0.0000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 31:
                df = new DecimalFormat("¥#,##0.00000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 32:
                df = new DecimalFormat("¥#,##0.000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 33:
                df = new DecimalFormat("¥#,##0.0000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 34:
                df = new DecimalFormat("¥#,##0.00000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 8:
                df = new DecimalFormat("$#,##0.00");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 17:
                df = new DecimalFormat("$#,##0.000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 18:
                df = new DecimalFormat("$#,##0.0000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 35:
                df = new DecimalFormat("$#,##0.00000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 36:
                df = new DecimalFormat("$#,##0.000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 37:
                df = new DecimalFormat("$#,##0.0000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 38:
                df = new DecimalFormat("$#,##0.00000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 9:
                df = new DecimalFormat("€#,##0.00");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 19:
                df = new DecimalFormat("€#,##0.000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 20:
                df = new DecimalFormat("€#,##0.0000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 39:
                df = new DecimalFormat("€#,##0.00000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 40:
                df = new DecimalFormat("€#,##0.000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 41:
                df = new DecimalFormat("€#,##0.0000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 42:
                df = new DecimalFormat("€#,##0.00000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 10:
                df = new DecimalFormat("HK$#,##0.00");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 21:
                df = new DecimalFormat("HK$#,##0.000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 22:
                df = new DecimalFormat("HK$#,##0.0000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 43:
                df = new DecimalFormat("HK$#,##0.00000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 44:
                df = new DecimalFormat("HK$#,##0.000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 45:
                df = new DecimalFormat("HK$#,##0.0000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 46:
                df = new DecimalFormat("HK$#,##0.00000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            //追加小数
            case 23:
                df = new DecimalFormat("###,##0.00000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 24:
                df = new DecimalFormat("###,##0.000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 25:
                df = new DecimalFormat("###,##0.0000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            case 26:
                df = new DecimalFormat("###,##0.00000000");
                df.setRoundingMode(RoundingMode.DOWN);
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
                break;
            default:
                break;
        }

    }


    //处理日期数据
    private void parseDate(BizObjectModel bizObjectModel, BizQueryColumnModel columnModel, BizQueryModel bizQuery) {
        List<BizQueryColumnModel> queryColumns = bizQuery.getQueryColumns();
        BizQueryColumnModel bizQueryColumnMode = null;
        for (BizQueryColumnModel bizQueryColumnModel : queryColumns) {
            String propertyCode = columnModel.getPropertyCode();
            String propertyCode1 = bizQueryColumnModel.getPropertyCode();
            if (StringUtils.isEmpty(propertyCode) || StringUtils.isEmpty(propertyCode1)) {
                continue;
            }
            boolean exits = bizQueryColumnModel.getPropertyType().equals(BizPropertyType.DATE) && Objects.equals(propertyCode, propertyCode1);
            if (exits) {
                if (bizQueryColumnModel == null) {
                    continue;
                }
                bizQueryColumnMode = bizQueryColumnModel;
            }
        }
        if (bizObjectModel.getData().get(columnModel.getPropertyCode()) == null) {
            return;
        }
        SimpleDateFormat df = null;
        if (bizQueryColumnMode == null) {
            df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.getData().get(columnModel.getPropertyCode())));
            return;
        }
        Integer displayFormat = bizQueryColumnMode.getDisplayFormat();
        if (displayFormat == null) {
            displayFormat = 0;
        }
        Object dt = bizObjectModel.getData().get(columnModel.getPropertyCode());
        Date date;
        if (!(dt instanceof Date)) {
            String[] pattern = {"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "yyyy", "yyyy-MM", "yyyy-MM-dd HH", "yyyy-MM-dd HH:mm"};
            try {
                date = DateUtils.parseDate(dt.toString(), pattern);
            } catch (ParseException e) {
                log.warn(e.getMessage(), e);
                throw new RuntimeException(e.getMessage());
            }
        } else {
            date = (Date) dt;
        }
        switch (displayFormat) {
            case 1:
                df = new SimpleDateFormat("yyyy-MM-dd") {
                };
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(date));
                break;
            case 2:
            case 0:
                df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(date));
                break;
            case 3:
                df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(date));
                break;
            case 4:
                df = new SimpleDateFormat("yyyy-MM");
                bizObjectModel.put(columnModel.getPropertyCode(), df.format(date));
                break;
            default:
                break;
        }
    }


    @Override
    public List<String> queryBizObjectIds(BizObjectQueryModel bizObjectQueryModel) {
        final String schemaCode = bizObjectQueryModel.getSchemaCode();
        final String queryCode = bizObjectQueryModel.getQueryCode();
        final ClientType clientType = Objects.nonNull(bizObjectQueryModel.getClientType()) ? bizObjectQueryModel.getClientType() : ClientType.PC;
        if (StringUtils.isEmpty(schemaCode) && StringUtils.isEmpty(queryCode)) {
            throw new ServiceException(ErrCode.BIZ_QUERY_CODE_SCHEMACODE_NOT_EXIST, bizObjectQueryModel);
        }

        final BizQuery bizQuery = bizQueryService.getBySchemaCodeAndCode(schemaCode, queryCode);
        if (bizQuery == null) {
            log.debug("bizQuery is null. {}", queryCode);
            throw new ServiceException(ErrCode.BIZ_QUERY_NOT_EXIST, queryCode);
        }
        String queryId = bizQuery.getId();
        //排序信息
        List<BizQuerySort> sorts = bizQuerySortService.getListByQueryId(queryId);
        sorts = sorts.stream().filter(t -> Objects.equals(clientType, t.getClientType())).collect(Collectors.toList());
        final List<OrderImpl> orders = new ArrayList<>();
        if (CollectionUtils.isEmpty(sorts)) {
            //使用默认排序
            orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));
        } else {
            orders.addAll(getOrders(sorts));
        }
        List<String> columnList = Lists.newArrayList();
        final List<String> bizObjectIds = bizObjectService.queryBizObjectIds(new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {
                return bizObjectQueryModel.getFilterExpr();
            }

            @Override
            public List<String> getDisplayFields() {
                columnList.add(DefaultPropertyType.ID.getCode());
                return columnList;
            }

            @Override
            public Pageable getPageable() {
                return bizObjectQueryModel.getPageable();
            }

            @Override
            public Sortable getSortable() {
                return orders == null ? null : new SortableImpl(orders);
            }
        });

        return bizObjectIds;
    }

    /**
     * 处理查询列表最终需要查询的字段
     *
     * @param schemaCode 模型编码
     * @param queryCode  查询列表编码
     * @param queryId    查询列表id
     * @param options    查询列表配置项
     * @return 需要查询的字段
     */
    private List<String> listQueryColumn(String schemaCode, String queryCode, String queryId, BizObjectQueryModel.Options options, ClientType clientType, Boolean display) {
        QueryDisplayType displayType = QueryDisplayType.DEFAULT;
        if (options != null) {
            displayType = options.getQueryDisplayType();
        }

        final List<String> columnList = Lists.newArrayList();
        switch (displayType) {
            case DEFAULT:
            case APPEND:
                //获取需要展示的列信息
                List<BizQueryColumn> columnTemplates = bizQueryColumnService.getListByQueryId(queryId);
                //新版列表设计展示字段区分客户端
                columnTemplates = columnTemplates.stream().filter(t -> Objects.equals(clientType, t.getClientType())).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(columnTemplates)) {
                    log.warn("查询列表信息展示列不能为空.");
                    throw new ServiceException(ErrCode.BIZ_QUERY_DISPLAY_COLUMNS_NOT_EMPTY, queryCode);
                }

                //处理列表脏数据
                final List<BizProperty> propertyList = bizPropertyService.getListBySchemaCode(schemaCode, null);
                final List<String> codes = getPropertyCodes(propertyList);
                if (display) {
                    columnList.addAll(codes);
                } else {
                    for (BizQueryColumn columnTemplate : columnTemplates) {
                        if (codes.contains(columnTemplate.getPropertyCode())) {
                            columnList.add(columnTemplate.getPropertyCode());
                        }

                    }
                }

                if (displayType == QueryDisplayType.APPEND) {
                    log.debug("APPEND mode.");
                    final List<String> appendColumns = options.getCustomDisplayColumns();

                    if (CollectionUtils.isNotEmpty(appendColumns)) {
                        if (log.isDebugEnabled()) {
                            log.debug("OVERRIDE columns = {}", JSON.toJSONString(appendColumns));
                        }
                        columnList.addAll(appendColumns);
                    }

                }
                break;

            case OVERRIDE:
                log.debug("OVERRIDE mode.");
                final List<String> overRideColumns = options.getCustomDisplayColumns();
                if (CollectionUtils.isEmpty(overRideColumns)) {
                    log.warn("查询列表显示模式为OVERRIDE时，显示字段不能为空.");
                    throw new ServiceException(ErrCode.BIZ_QUERY_COLUMNS_NOT_EMPTY_FOR_OVERRIDE, queryCode);
                }
                if (log.isDebugEnabled()) {
                    log.debug("OVERRIDE columns = {}", JSON.toJSONString(overRideColumns));
                }
                columnList.addAll(overRideColumns);
                break;
            default:
                log.warn("查询列表显示模式不能为空.");
                throw new ServiceException(ErrCode.BIZ_QUERY_DISPLAY_MODE_NOT_EMPTY, queryCode);
        }
        return columnList;
    }

    /**
     * 获取排序信息
     *
     * @param sorts
     * @return
     */
    private List<OrderImpl> getOrders(List<BizQuerySort> sorts) {
        List<OrderImpl> orders = new ArrayList<>();
        sorts.stream().forEach(sort -> {
            orders.add(new OrderImpl(sort.getPropertyCode(), SortDirectionType.ASC.equals(sort.getDirection()) ? Order.Dir.ASC : Order.Dir.DESC));
        });
        return orders.size() > 0 ? orders : null;
    }

    @Override
    public Boolean removeBizObjects(String userId, String schemaCode, List<String> objectIds) {

        // 树形模型删除校验
        if (bizObjectConverter.checkTreeExistChild(schemaCode, objectIds)) {
            throw new ServiceException(ErrCode.BIZ_OBJECT_TREE_MODEL_EXIST_CHILD);
        }
        for (Object obj : objectIds) {
            String objectId;
            if (obj instanceof String) {
                objectId = (String) obj;
            } else {
                objectId = obj.toString();
            }

            removeBizObject(userId, schemaCode, objectId);
        }
        return Boolean.TRUE;
    }

    @Override
    public List<CheckResultForRemoveBizObject> checkForRemoveBizObject(String schemaCode, List<String> objectIds, List<String> noDeleteIDs) {
        List<CheckResultForRemoveBizObject> list = new ArrayList<>(objectIds.size());
        List<BizPropertyModel> bizPropertyModelList = ModelUtil.toModel(bizPropertyService.getListByRelativeCode(schemaCode), BizPropertyModel.class);
        bizPropertyModelList = bizPropertyModelList.stream().filter(item -> item.getPropertyType() == BizPropertyType.WORK_SHEET || item.getPropertyType() == BizPropertyType.MULT_WORK_SHEET).collect(Collectors.toList());
        Map<String, List<BizPropertyModel>> bizPropertyMap = bizPropertyModelList.stream().collect(Collectors.groupingBy(BizPropertyModel::getSchemaCode));
        for (Object obj : objectIds) {
            CheckResultForRemoveBizObject checkResult = new CheckResultForRemoveBizObject();
            String objectId;
            if (obj instanceof String) {
                objectId = (String) obj;
            } else {
                objectId = obj.toString();
            }
            WorkflowInstanceModel instance = bizWorkflowInstanceService.getByObjectId(objectId);
            if (instance == null) {
                checkResult.setResultCode(CheckResultForRemoveBizObject.CheckResultCode.BIZ_DATA);
            } else {
                boolean isParentWf = false;
                boolean isChildWf = false;
                List<WorkflowInstanceModel> childInstances = bizWorkflowInstanceService.getWorkflowInstanceByParentId(instance.getId());
                if (CollectionUtils.isNotEmpty(childInstances)) {
                    checkResult.setResultCode(CheckResultForRemoveBizObject.CheckResultCode.PARENT_WF_DATA);
                    isParentWf = true;
                }
                if (StringUtils.isNotBlank(instance.getParentId())) {
                    checkResult.setResultCode(CheckResultForRemoveBizObject.CheckResultCode.CHILD_WF_DATA);
                    isChildWf = true;
                }
                if (!isParentWf && !isChildWf) {
                    if (instance.getState() == WorkflowInstanceStatus.DRAFT) {
                        checkResult.setResultCode(CheckResultForRemoveBizObject.CheckResultCode.WF_DRAFT_DATA);
                    } else {
                        checkResult.setResultCode(CheckResultForRemoveBizObject.CheckResultCode.ONLY_WF_DATA);
                    }
                }
            }
            checkResult.setObjectId(objectId);
            list.add(checkResult);
        }
        //遍历关联数据模型
        checkRelative(list, bizPropertyMap, objectIds);

        for (String id : noDeleteIDs) {
            CheckResultForRemoveBizObject checkResult = new CheckResultForRemoveBizObject();
            checkResult.setResultCode(CheckResultForRemoveBizObject.CheckResultCode.NO_DELETE_WF_DATA);
            checkResult.setObjectId(id);
            list.add(checkResult);
        }
        return list;
    }

    /**
     * 校验是否存在关联的业务数据
     *
     * @param list
     * @param bizPropertyMap
     * @param objectIds
     */
    private void checkRelative(List<CheckResultForRemoveBizObject> list, Map<String, List<BizPropertyModel>> bizPropertyMap, List<String> objectIds) {
        int count = 0;
        CountDownLatch countDownLatch = new CountDownLatch(bizPropertyMap.size() > 10 ? 10 : bizPropertyMap.size());
        Map<String, String> concurrentHashMap = new ConcurrentHashMap<>();
        for (Map.Entry<String, List<BizPropertyModel>> map : bizPropertyMap.entrySet()) {
            //未避免关联模型过多导致性能问题，现只查前10个模型数据
            count++;
            if (count > 10) {
                break;
            }
            checkRelativePool.execute(() -> {
                try {
                    Set<String> relativeIds = new HashSet<>();
                    BizPropertyModel bizPropertyModel = ModelUtil.toModel(bizPropertyService.getByPropertyCode(map.getKey()), BizPropertyModel.class);
                    if (bizPropertyModel != null && BizPropertyType.CHILD_TABLE == bizPropertyModel.getPropertyType()) {
                        //子表关联
                        childTableRelativeCheck(map, objectIds, relativeIds, bizPropertyModel);
                    } else {
                        //非子表关联
                        mainTableRelativeCheck(map, objectIds, relativeIds);

                    }
                    //是否存在关联数据判断
                    if (CollectionUtils.isEmpty(relativeIds)) {
                        return;
                    }
                    BizSchema bizSchema = bizSchemaService.getBySchemaCode(bizPropertyModel != null ? bizPropertyModel.getSchemaCode() : map.getKey());
                    //组装map，key=关联Id，value=关联模型名称（拼接）
                    relativeIds.forEach(str -> {
                        String modelName = concurrentHashMap.get(str);
                        if (StringUtils.isBlank(modelName)) {
                            concurrentHashMap.put(str, bizSchema.getName());
                        } else {
                            concurrentHashMap.put(str, modelName + '、' + bizSchema.getName());
                        }
                    });
                } catch (Exception e) {
                    log.error("处理失败", e);
                } finally {
                    countDownLatch.countDown();
                }
            });
        }
        //等待线程执行完
        try {
            countDownLatch.await();
            //遍历删除数据赋值关联模型
            list.forEach(item -> {
                if (concurrentHashMap.containsKey(item.getObjectId())) {
                    item.setRelativeModel(concurrentHashMap.get(item.getObjectId()));
                }
            });
        } catch (InterruptedException e) {
            log.error("[data delete checkRelative] countDownLatch await error. ", e);
        }
    }

    private void childTableRelativeCheck(Map.Entry<String, List<BizPropertyModel>> map, List<String> objectIds, Set<String> relativeIds, BizPropertyModel bizPropertyModel) {
        BizObjectQueryObject bizObjectQueryObject = new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return map.getKey();
            }

            @Override
            public FilterExpression getFilterExpression() {
                List<FilterExpression> filterExpressions = new ArrayList<>();
                map.getValue().forEach(t -> {
                    if (t.getPropertyType() == BizPropertyType.WORK_SHEET) {
                        filterExpressions.add(Q.it(t.getCode(), FilterExpression.Op.In, objectIds));
                    } else if (t.getPropertyType() == BizPropertyType.MULT_WORK_SHEET) {
                        String objectIdStr = String.join("|", objectIds);
                        filterExpressions.add(Q.it(t.getCode(), FilterExpression.Op.Reg, objectIdStr));
                    }
                });
                if (filterExpressions.size() == 1) {
                    return filterExpressions.get(0);
                } else {
                    return Q.or(filterExpressions);
                }
            }

            @Override
            public List<String> getDisplayFields() {
                HashSet<String> displayFields = Sets.newHashSet();
                map.getValue().forEach(t -> displayFields.add(t.getCode()));
                return new ArrayList<>(displayFields);
            }
        };
        //查询子表中是否存在关联数据
        List<Map<String, Object>> chilData = bizObjectConverter.findChildTableData(map.getKey(), bizObjectQueryObject);
        if (CollectionUtils.isNotEmpty(chilData)) {
            chilData.forEach(item ->
                    item.forEach((k, v) -> {
                        if (!Objects.isNull(v)) {
                            List<String> strList = Arrays.asList(String.valueOf(v).split(";"));
                            relativeIds.addAll(strList);
                        }
                    })
            );
        }
    }

    private void mainTableRelativeCheck(Map.Entry<String, List<BizPropertyModel>> map, List<String> objectIds, Set<String> relativeIds) {
        //数据查询
        Page<Map<String, Object>> page = bizObjectService.queryBizObjects(new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return map.getKey();
            }

            @Override
            public FilterExpression getFilterExpression() {
                List<FilterExpression> filterExpressions = new ArrayList<>();
                map.getValue().forEach(t -> {
                    if (t.getPropertyType() == BizPropertyType.WORK_SHEET) {
                        filterExpressions.add(Q.it(t.getCode(), FilterExpression.Op.In, objectIds));
                    } else if (t.getPropertyType() == BizPropertyType.MULT_WORK_SHEET) {
                        String objectIdStr = String.join("|", objectIds);
                        filterExpressions.add(Q.it(t.getCode(), FilterExpression.Op.Reg, objectIdStr));
                    }
                });
                if (filterExpressions.size() == 1) {
                    return filterExpressions.get(0);
                } else {
                    return Q.or(filterExpressions);
                }
            }

            @Override
            public List<String> getDisplayFields() {
                HashSet<String> displayFields = Sets.newHashSet();
                map.getValue().forEach(t -> displayFields.add(t.getCode()));
                return new ArrayList<>(displayFields);
            }
        });
        if (page.getTotal() == 0) {
            return;
        }

        //将数据中所有关联的ID抽成set
        page.getContent().forEach(item ->
                item.forEach((k, v) -> {
                    if (!Objects.isNull(v)) {
                        List<String> strList = Arrays.asList(String.valueOf(v).split(";"));
                        relativeIds.addAll(strList);
                    }
                })
        );

    }

    @Override
    public long countBizObject(String userId, String schemaCode) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(schemaCode)) {
            log.debug("用户Id或schemaCode为空.");
            throw new ServiceException(ErrCode.SYS_PARAMETER_EMPTY);
        }

        getUser(userId);
        try {
            return bizObjectService.countBizObject(schemaCode);
        } catch (Exception e) {
            log.error("countBizObject happen exception. ", e);
        }
        return 0L;
    }

    @Override
    public List<BizCommentModel> getComments(String workflowInstanceId, String tokenId) {
        log.info("加载审批意见. workflowInstanceId = {}, tokenId = {}", workflowInstanceId, tokenId);
        List<Comment> tempComments;

        if (StringUtils.isEmpty(tokenId)) {
            tempComments = bizObjectService.listWorkflowInstanceComments(workflowInstanceId);
        } else {
            tempComments = bizObjectService.listWorkflowInstanceComments(workflowInstanceId, tokenId);
            tempComments = tempComments.stream().filter(comment -> ActionType.APPROVAL == comment.getActionType()).collect(Collectors.toList());
        }

        if (log.isTraceEnabled()) {
            log.trace("comments = {}", JSONObject.toJSONString(tempComments));
        }

        if (CollectionUtils.isEmpty(tempComments)) {
            return Collections.EMPTY_LIST;
        }

        List<BizCommentModel> models = Lists.newArrayList();

        for (Comment c : tempComments) {
            BizCommentModel model = new BizCommentModel();
            model.setId(c.getId());
            model.setContent(c.getContent());
            model.setWorkItemId(c.getWorkItemId());
            model.setCommentTime(c.getCreatedTime());
            model.setBizPropertyCode(c.getBizPropertyCode());
            model.setRelUsers(SelectionValue.toListMap(c.getRelUsers()));
            model.setResult(c.getResult());
            model.setWorkflowTokenId(c.getWorkflowTokenId());
            model.setCreater(SelectionValue.toMap(c.getCreater()));
            model.setTokenId(c.getTokenId());
            model.setActivityCode(c.getActivityCode());
            model.setActivityName(c.getActivityName());
            model.setActionType(c.getActionType());
            model.setResources(getAttachments(c.getAttachments()));
            model.setCreatedTime(c.getCreatedTime());
            models.add(model);
        }
        return models;
    }

    @Override
    public AttachmentModel getAttachmentByRefId(String refId) {
        Optional<Attachment> resource = bizObjectService.getAttachmentByRefId(refId);
        if (!resource.isPresent()) {
            return null;
        }
        AttachmentModel model = new AttachmentModel();
        model.setId(resource.get().getId());
        model.setRefId(resource.get().getRefId());
        model.setName(resource.get().getName());
        model.setFileExtension(resource.get().getFileExtension());
        model.setFileSize(resource.get().getFileSize());
        model.setMimeType(resource.get().getMimeType());
        return model;
    }

    @Override
    public AttachmentModel getFormCommentAttachmentByRefId(String attachmentId) {
        BizFormCommentAttachment resource = bizFormCommentService.getFormCommentAttachmentByRefId(attachmentId);
        if (resource == null) {
            return null;
        }
        AttachmentModel model = new AttachmentModel();
        model.setId(resource.getId());
        model.setRefId(resource.getRefId());
        model.setName(resource.getName());
        model.setFileExtension(resource.getFileExtension());
        model.setFileSize(resource.getFileSize());
        model.setMimeType(resource.getMimeType());
        return model;
    }

    @Override
    public Integer batchInsertAttachments(List<AttachmentModel> attachmentModelList) {
        return bizObjectService.insertAttachments(attachmentModelList);
    }

    /**
     * 附件对象转换
     *
     * @param resources
     * @return
     */
    private List<AttachmentModel> getAttachments(List<? extends Attachment> resources) {
        List<AttachmentModel> rms = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(resources)) {
            for (Attachment r : resources) {
                AttachmentModel rm = new AttachmentModel();
                rm.setId(r.getId());
                rm.setRefId(r.getRefId());
                rm.setName(r.getName());
                rm.setFileExtension(r.getFileExtension());
                rm.setFileSize(r.getFileSize());
                rms.add(rm);
            }
        }
        return rms;
    }

    @Override
    public PairSettingModel savePairSetting(PairSettingModel pairSettingModel) {
        if (log.isTraceEnabled()) {
            log.trace("savePairSetting 参数:{}", JSON.toJSONString(pairSettingModel));
        }
        //数据已存在时，直接使用原有数据
        try {
            // 解析json数据
            parseDataFromValue(pairSettingModel);

            if (StringUtils.isNotBlank(pairSettingModel.getObjectId()) && StringUtils.isNotBlank(pairSettingModel.getFormCode())) {
                List<PairSetting> pairValueList = pairSettingService.findByObjectIdAndFormCode(pairSettingModel.getObjectId(), pairSettingModel.getFormCode());
                if (CollectionUtils.isNotEmpty(pairValueList)) {
                    return ModelUtil.toModel(pairValueList.get(0), PairSettingModel.class);
                }
            }
        } catch (Exception e) {
        }
        PairSetting pairSetting = pairSettingService.save(ModelUtil.toEntity(pairSettingModel, PairSetting.class));
        return ModelUtil.toModel(pairSetting, PairSettingModel.class);
    }

    private PairSettingModel parseDataFromValue(PairSettingModel pairSettingModel) {
        String pairValue = pairSettingModel.getPairValue();
        if (!JSONUtil.isJson(pairValue)) {
            return pairSettingModel;
        }
        cn.hutool.json.JSONObject pairValueJson = JSONUtil.parseObj(pairValue);
        String objectId = pairValueJson.getStr("objectId");
        if (objectId == null) {
            objectId = pairValueJson.getStr("id");
        }
        String formCode = pairValueJson.getStr("formCode");
        if (formCode == null) {
            formCode = pairValueJson.getStr("sheetCode");
        }
        String schemaCode = pairValueJson.getStr("schemaCode");
        String workflowInstanceId = pairValueJson.getStr("workflowInstanceId");
        pairSettingModel.setObjectId(objectId);
        pairSettingModel.setSchemaCode(schemaCode);
        pairSettingModel.setFormCode(formCode);
        pairSettingModel.setWorkflowInstanceId(workflowInstanceId);
        return pairSettingModel;
    }

    @Override
    public PairSettingModel findByPairCode(String pairCode) {
        if (log.isTraceEnabled()) {
            log.trace("findByPairCode 参数:{}", JSON.toJSONString(pairCode));
        }
        PairSetting pairSetting = pairSettingService.findByPairCode(pairCode);
        return ModelUtil.toModel(pairSetting, PairSettingModel.class);
    }

    @Override
    public List<PairSettingModel> findAllPairSetting() {
        List<PairSetting> list = this.pairSettingService.findAll();
        return CollectionUtils.isEmpty(list) ? Collections.emptyList() : ModelUtil.toModel(list, PairSettingModel.class);
    }

    @Override
    public List<Map<String, Object>> getChildDatas(String parentId, String subSchemaCode) {
        return bizObjectConverter.fromDbChildTableValue(subSchemaCode, parentId, true);
    }

    /**
     * 批量生成短码
     * 该接口不考虑重复请求，一次请求生成一批短码
     *
     * @param pairSettingModels
     * @return
     */
    @Override
    public List<PairSettingModel> savePairCodes(List<PairSettingModel> pairSettingModels) {
        if (org.springframework.util.CollectionUtils.isEmpty(pairSettingModels)) {
            return Collections.EMPTY_LIST;
        }
        List<PairSettingModel> modelList = new ArrayList<>();
        for (PairSettingModel settingModel : pairSettingModels) {
            parseDataFromValue(settingModel);
            PairSetting pairSetting = pairSettingService.save(ModelUtil.toEntity(settingModel, PairSetting.class));
            modelList.add(ModelUtil.toModel(pairSetting, PairSettingModel.class));
        }
        return modelList;
    }

    @Override
    public Page<BizObjectModel> queryBizObjectItemDatas(String owner, String schemaCode, String sequenceStatus, Integer page, Integer size) {
        if (StringUtils.isEmpty(owner)) {
            return new PageImpl<>(0L, Lists.newArrayList());
        }
        //当没有模型编码的时候
        if (!StringUtils.isEmpty(schemaCode)) {
            List<FilterExpression> filterExprValues = new ArrayList<>();
            FilterExpression filterExprValue = FilterExpression.empty;
            //获取数据查询条件
            filterExprValues.add(Q.it(DefaultPropertyType.OWNER.getCode(), FilterExpression.Op.Eq, owner));
            if (!StringUtils.isEmpty(sequenceStatus)) {
                String[] sequences = sequenceStatus.split(";");
                filterExprValues.add(Q.it(DefaultPropertyType.SEQUENCE_STATUS.getCode(), FilterExpression.Op.In, Arrays.asList(sequences)));
            }
            if (filterExprValues.size() == 1) {
                filterExprValue = filterExprValues.get(0);
            } else if (filterExprValues.size() > 1) {
                filterExprValue = Q.and(filterExprValues);
            }

            BizObjectQueryModel bizObjectQueryModel = new BizObjectQueryModel();
            bizObjectQueryModel.setFilterExpr(filterExprValue);

            //分页信息
            PageableImpl pageable = new PageableImpl(page * size, size);
            bizObjectQueryModel.setPageable(pageable);
            bizObjectQueryModel.setSchemaCode(schemaCode);
            bizObjectQueryModel.setQueryCode(schemaCode);
            bizObjectQueryModel.setClientType(ClientType.PC);
            Page<BizObjectModel> bizObjectModelPage = queryTransferBizObjects(bizObjectQueryModel);


            return bizObjectModelPage;
        }
        return new PageImpl<>(0L, Lists.newArrayList());
    }


    @Override
    public String getTableName(String schemaCode) {
        return db.ddl().getTableName(schemaCode);
    }

    @Override
    public BizFormModel getTempAuthSchemaCodes(String sheetId) {
        return ModelUtil.toModel(bizFormService.getTempAuthSchemaCodesBySheetId(sheetId), BizFormModel.class);
    }

    @Override
    public Page<BizObjectModel> queryBizObjectSkipQuery(BizObjectQueryModel bizObjectQueryModel) {
        String schemaCode = bizObjectQueryModel.getSchemaCode();
        final Page<Map<String, Object>> queryData = bizObjectService.queryBizObjects(new BizObjectQueryObject() {
            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {
                return bizObjectQueryModel.getFilterExpr();
            }

            @Override
            public List<String> getDisplayFields() {
                List<String> groupByFields = bizObjectQueryModel.getGroupByFields();
                if (CollectionUtils.isNotEmpty(groupByFields)) {
                    return groupByFields;
                }

                List<String> orderByFields = bizObjectQueryModel.getOrderByFields();

                //下拉框关联业务模型：：自定义排序时，指定查询列表信息
                if (CollectionUtils.isNotEmpty(orderByFields)) {
                    BizObjectQueryModel.Options options = bizObjectQueryModel.getOptions();
                    if (options != null && options.getQueryDisplayType().equals(QueryDisplayType.OVERRIDE)) {
                        List<String> columnList = Lists.newArrayList();
                        List<String> customDisplayColumns = options.getCustomDisplayColumns();
                        columnList.addAll(customDisplayColumns);
                        return columnList;
                    }
                }

                BizObjectQueryModel.Options options = bizObjectQueryModel.getOptions();
                if (options != null) {
                    List<String> columnList = Lists.newArrayList();
                    List<String> customDisplayColumns = options.getCustomDisplayColumns();
                    columnList.addAll(customDisplayColumns);
                    if (!columnList.contains(DefaultPropertyType.ID.getCode())) {
                        columnList.add(DefaultPropertyType.ID.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.NAME.getCode())) {
                        columnList.add(0, DefaultPropertyType.NAME.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.OWNER.getCode())) {
                        columnList.add(DefaultPropertyType.OWNER.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.CREATER.getCode())) {
                        columnList.add(DefaultPropertyType.CREATER.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.CREATED_TIME.getCode())) {
                        columnList.add(DefaultPropertyType.CREATED_TIME.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.MODIFIED_TIME.getCode())) {
                        columnList.add(DefaultPropertyType.MODIFIED_TIME.getCode());
                    }
                    if (!columnList.contains(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
                        columnList.add(DefaultPropertyType.SEQUENCE_STATUS.getCode());
                    }
                    return columnList;
                }
                return bizPropertyService.getListBySchemaCode(schemaCode, true).stream().map(p -> p.getCode()).collect(Collectors.toList());
            }

            @Override
            public Sortable getSortable() {
                ArrayList<OrderImpl> orders = Lists.newArrayList();

                List<String> orderByFields = bizObjectQueryModel.getOrderByFields();
                int orderType = bizObjectQueryModel.getOrderType();
                if (CollectionUtils.isNotEmpty(orderByFields)) {
                    orderByFields.forEach(fields -> {
                        orders.add(new OrderImpl(fields, orderType == 2 ? Order.Dir.DESC : Order.Dir.ASC));
                    });
                    return new SortableImpl(orders);
                }

                List<String> groupByFields = bizObjectQueryModel.getGroupByFields();
                if (CollectionUtils.isNotEmpty(groupByFields)) {
                    return new SortableImpl(orders);
                }

                orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.ASC));
                return new SortableImpl(orders);
            }

            @Override
            public Pageable getPageable() {
                return bizObjectQueryModel.getPageable();
            }

            @Override
            public List<String> getGroupByFields() {
                return bizObjectQueryModel.getGroupByFields();
            }
        });
        //转换WEB-API需要的数据
        final List<BizObjectModel> bizObjectList = new ArrayList<>();
        for (Map<String, Object> map : queryData.getContent()) {
            final BizObjectModel bizObjectModel = new BizObjectModel(schemaCode, map, false);
            bizObjectList.add(bizObjectModel);
        }
        if (log.isTraceEnabled()) {
            log.trace("==================bizObjectList={}", JSON.toJSONString(bizObjectList));
        }
        return new PageImpl<BizObjectModel>(queryData.getTotal(), bizObjectList);
    }

    @Override
    public String saveBizFormComment(BizFormCommentModel bizFormCommentModel) {
        return bizFormCommentService.saveBizFormComment(bizFormCommentModel);
    }

    @Override
    public void deleteBizFormComment(String id, String userId) {
        bizFormCommentService.deleteBizFormComment(id, userId);
    }

    @Override
    public BizFormCommentModel getBizFormCommentModel(String id) {
        BizFormComment bizFormComment = bizFormCommentService.get(id);
        return ModelUtil.toModel(bizFormComment, BizFormCommentModel.class);
    }

    @Override
    public org.springframework.data.domain.Page<BizFormCommentModel> fromCommentList(String bizObjectId, String schemaCode, int page, int pageSize) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        final org.springframework.data.domain.Pageable pageable = PageRequest.of(Math.max(page, 0), Math.min(pageSize, 200), sort);
        org.springframework.data.domain.Page<BizFormCommentModel> bizFormCommentPage = bizFormCommentService.queryBizFormCommentByBizObjectIdAndSchemaCode(bizObjectId, schemaCode, pageable);
        if (bizFormCommentPage == null || CollectionUtils.isEmpty(bizFormCommentPage.getContent())) {
            return bizFormCommentPage;
        }
        final org.springframework.data.domain.Pageable replyPageable = PageRequest.of(0, 2, sort);
        bizFormCommentPage.getContent().forEach(it -> {
            org.springframework.data.domain.Page<BizFormCommentModel> replyCommentPage = bizFormCommentService.queryReplyComment(it.getId(), bizObjectId, schemaCode, replyPageable);
            if (replyCommentPage == null || CollectionUtils.isEmpty(replyCommentPage.getContent())) {
                return;
            }
            it.setReplies(replyCommentPage.getContent());
            it.setReplyCount(replyCommentPage.getTotalElements());

        });
        return bizFormCommentPage;
    }

    @Override
    public org.springframework.data.domain.Page<BizFormCommentModel> replyCommentList(String commentId, int page, int pageSize) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        final org.springframework.data.domain.Pageable pageable = PageRequest.of(Math.max(page, 0), Math.min(pageSize, 50), sort);
        BizFormComment bizFormComment = bizFormCommentService.get(commentId);
        if (bizFormComment == null) {
            log.warn("评论[{}]不存在", commentId);
            return org.springframework.data.domain.Page.empty(pageable);
        }
        return bizFormCommentService.queryReplyComment(commentId, bizFormComment.getBizObjectId(), bizFormComment.getSchemaCode(), pageable);
    }

    @Override
    public Integer countBizFormComment(String bizObjectId, String schemaCode) {
        return bizFormCommentService.countByBizObjectAndSchemaCode(bizObjectId, schemaCode);
    }

    @Override
    public org.springframework.data.domain.Page<SelectionValue> pullPerson(String keyword, String bizObjectId, String schemaCode, String wfInstanceId, org.springframework.data.domain.Pageable pageable) {
        return bizFormCommentService.pullPerson(keyword, bizObjectId, schemaCode, wfInstanceId, pageable);
    }

    @Override
    public Map<String, List<SelectionValue>> getSecondImportDatas(String code, String schemaCode, String corpId, Map<String, Object> map, OrgType orgType) {
        Map<String, List<SelectionValue>> selectionValueMap = new HashMap<>();
        BizProperty bizProperty = bizPropertyService.get(schemaCode, code);
        Boolean propertyEmpty = bizProperty.getPropertyEmpty();
        Object o = map.get(code);
        boolean empty = Objects.isNull(o);
        //TODO此处的propertyEmpty需要再次确认
        if (empty && propertyEmpty) {
            return Maps.newHashMap();
        }

        List<Map<String, Object>> selectionValues = (List<Map<String, Object>>) o;

        if ((CollectionUtils.isEmpty(selectionValues) || MapUtils.isEmpty(selectionValues.get(0)) || Objects.isNull(selectionValues.get(0).get("id")) || StringUtils.isBlank(selectionValues.get(0).get("id").toString())) && propertyEmpty) {
            return Maps.newHashMap();
        }
        List<SelectionValue> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(selectionValues)) {
            selectionValueMap.put(code, null);
            return selectionValueMap;
        }
        for (Map<String, Object> selectionValue : selectionValues) {
            Object type = selectionValue.get("type");
            Integer unitType = Integer.valueOf(type.toString());
            String id = (String) selectionValue.get("id");
            Boolean boo = validateSelectionImportDatas(id, corpId, unitType, list, orgType);
            if (!boo) {
                return Maps.newHashMap();
            }
        }
        selectionValueMap.put(code, list);
        return selectionValueMap;
    }

    private Boolean validateSelectionImportDatas(String id, String corpId, Integer type, List<SelectionValue> list, OrgType orgType) {
        SelectionValue selectionValue = new SelectionValue();
        if (type == 3) {
            UserModel user = userFacade.get(id);
            if (user == null || UserStatus.DISABLE == user.getStatus()) {
                return Boolean.FALSE;
            }
            if (orgType != OrgType.MAIN) {
                if (StringUtils.isEmpty(user.getCorpId()) || !Objects.equals(corpId, user.getCorpId())) {
                    return Boolean.FALSE;
                }
            }
            selectionValue.setType(UnitType.USER);
            selectionValue.setId(id);
            selectionValue.setName(user.getName());
            list.add(selectionValue);
        } else if (type == 1) {
            DepartmentModel department = departmentFacade.get(id);
            if (department == null || Objects.equals(department.getDeleted(), true)) {
                return Boolean.FALSE;
            }
            if (orgType != OrgType.MAIN) {
                if (StringUtils.isEmpty(department.getCorpId()) || (!Objects.equals(corpId, department.getCorpId()))) {
                    return Boolean.FALSE;
                }
            }
            selectionValue.setType(UnitType.DEPARTMENT);
            selectionValue.setId(id);
            selectionValue.setName(department.getName());
            list.add(selectionValue);
        }
        return Boolean.TRUE;
    }

    @Override
    public Page<BizObjectModel> queryBizObjectsFilter(BizObjectQueryModel bizObjectQueryModel, List<Map<String, String>> filter, int page, int size) {
        final String schemaCode = bizObjectQueryModel.getSchemaCode();
        final String queryCode = bizObjectQueryModel.getQueryCode();
        final ClientType clientType = Objects.nonNull(bizObjectQueryModel.getClientType()) ? bizObjectQueryModel.getClientType() : ClientType.PC;
        if (StringUtils.isEmpty(schemaCode) && StringUtils.isEmpty(queryCode)) {
            throw new ServiceException(ErrCode.BIZ_QUERY_CODE_SCHEMACODE_NOT_EXIST, bizObjectQueryModel);
        }

        final BizQuery bizQuery = bizQueryService.getBySchemaCodeAndCode(schemaCode, queryCode);
        if (bizQuery == null) {
            log.debug("bizQuery is null. {}", queryCode);
            throw new ServiceException(ErrCode.BIZ_QUERY_NOT_EXIST, queryCode);
        }
        String queryId = bizQuery.getId();

        //排序信息
        List<BizQuerySort> sorts = bizQuerySortService.getListByQueryId(queryId);
        sorts = sorts.stream().filter(t -> Objects.equals(clientType, t.getClientType())).collect(Collectors.toList());
        final List<OrderImpl> orders = new ArrayList<>();
        if (CollectionUtils.isEmpty(sorts)) {
            //使用默认排序
            orders.add(new OrderImpl(DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));
        } else {
            orders.addAll(getOrders(sorts));
        }

        List<BizProperty> properties = bizPropertyService.getListBySchemaCode(schemaCode, true);
        if (CollectionUtils.isEmpty(properties)) {
            return new PageImpl<>(0, Lists.newArrayList());
        }

        QueryRelationObject queryRelationObject = null;
        // 多模型查询判断 (树形模型不支持多模型)
        if (bizObjectQueryModel.getView() == null || ModelViewType.LIST.equals(bizObjectQueryModel.getView().getType())) {
            queryRelationObject = buildRelationQueryObject(bizObjectQueryModel, queryId, schemaCode, clientType, sorts, properties);
        }
        // 树形控件作为查询条件 且 需要查询子数据时，构建关联查询 sprint33
        if (queryRelationObject == null) {
            queryRelationObject = buildRelationQueryObjectForTree(bizObjectQueryModel, queryId, clientType, sorts, properties);
        }
        List<String> columnList = null;
        if (queryRelationObject == null) {
            List<String> propertyCodes = properties.stream().filter(Objects::nonNull).map(BizProperty::getCode).collect(Collectors.toList());
            List<String> columns = listQueryColumn(schemaCode, queryCode, queryId, bizObjectQueryModel.getOptions(), clientType, bizObjectQueryModel.getDisplay());
            columnList = columns.stream().filter(propertyCodes::contains).collect(Collectors.toList());
            // 补全必要展示字段
            columnList = completeSystemFields(schemaCode, bizObjectQueryModel.getQuotes(), columnList);
            if (log.isDebugEnabled()) {
                log.debug("==================columnList={}", columnList);
            }
        }

        Pair<QueryRelationObject, List<String>> pair = Pair.of(queryRelationObject, columnList);
        final Page<Map<String, Object>> queryData = bizObjectService.queryBizObjects(new BizObjectQueryObject() {

            @Override
            public String getSchemaCode() {
                return schemaCode;
            }

            @Override
            public FilterExpression getFilterExpression() {
                return bizObjectQueryModel.getFilterExpr();
            }

            @Override
            public List<String> getDisplayFields() {
                return pair.getRight();
            }

            @Override
            public Pageable getPageable() {
                return bizObjectQueryModel.getPageable();
            }

            @Override
            public Sortable getSortable() {
                ArrayList<OrderImpl> dynamicOrders = Lists.newArrayList();

                List<String> orderByFields = bizObjectQueryModel.getOrderByFields();
                int orderType = bizObjectQueryModel.getOrderType();
                if (CollectionUtils.isNotEmpty(orderByFields)) {
                    orderByFields.forEach(fields -> {
                        dynamicOrders.add(new OrderImpl(fields, orderType == 2 ? Order.Dir.DESC : Order.Dir.ASC));
                    });
                    return new SortableImpl(dynamicOrders);
                }

                return orders == null ? null : new SortableImpl(orders);
            }

            @Override
            public Map<String, Object> getQuotes() {
                return bizObjectQueryModel.getQuotes();
            }

            public QueryRelationObject getQueryRelationObject() {
                return pair.getLeft();
            }

            public Map<String, Object> getViewType() {
                return BeanUtil.beanToMap(bizObjectQueryModel.getView());
            }

            public FilterExpression getAuthFilterExpression() {
                return bizObjectQueryModel.getAuthFilter();
            }

            public FilterExpression getFilterExpressionExcludeAuth() {
                return bizObjectQueryModel.getFilterExcludeAuth();
            }
        });

        //过滤关联表单多选
        List<Map<String, Object>> data = filterMultWorkSheet(queryData, filter);
        //分页
        long total = queryData.getTotal();
        long sum = data.size();
        if (!CollectionUtils.isEmpty(filter)) {
            data = getPageList(data, page, size);
            total = sum;
        }
        //转换WEB-API需要的数据
        final List<BizObjectModel> bizObjectList = buildBizObjectModel(schemaCode, data);

        if (log.isTraceEnabled()) {
            log.trace("==================bizObjectList={}", JSON.toJSONString(bizObjectList));
        }
        return new PageImpl<>(total, bizObjectList);
    }

    private List<String> completeSystemFields(String schemaCode, Map<String, Object> quotes, List<String> displayFields) {
        HashSet<String> displayFieldSet = Sets.newHashSet(DefaultPropertyType.ID.getCode(),
                DefaultPropertyType.NAME.getCode(),
                DefaultPropertyType.OWNER.getCode(),
                DefaultPropertyType.CREATER.getCode(),
                DefaultPropertyType.CREATED_TIME.getCode(),
                DefaultPropertyType.MODIFIED_TIME.getCode(),
                DefaultPropertyType.SEQUENCE_STATUS.getCode(),
                DefaultPropertyType.WORKFLOW_INSTANCE_ID.getCode());
        displayFieldSet.addAll(displayFields);

        //引用类型的关联表单的数据  必须返回
        if (MapUtils.isNotEmpty(quotes)) {
            Object o = quotes.get(schemaCode);
            if (Objects.nonNull(o)) {
                Map<String, List<QuoteModel>> map = (Map<String, List<QuoteModel>>) o;
                Set<String> workSheets = map.keySet();
                if (!workSheets.isEmpty()) {
                    displayFieldSet.addAll(workSheets);
                }
            }
        }
        return new ArrayList<>(displayFieldSet);
    }

    private List<BizObjectModel> buildBizObjectModel(String schemaCode, List<Map<String, Object>> data) {
        List<BizObjectModel> bizObjectList = new ArrayList<>();
        for (Map<String, Object> map : data) {
            Object childrenObj = map.get(ModelConstant.TREE_MODEL_QUERY_CHILDREN_KEY);
            if (childrenObj != null) {
                map.put(ModelConstant.TREE_MODEL_QUERY_CHILDREN_KEY, buildBizObjectModel(schemaCode, (List<Map<String, Object>>) childrenObj));
            }
            final BizObjectModel bizObjectModel = new BizObjectModel(schemaCode, map, false);
            bizObjectList.add(bizObjectModel);
        }
        return bizObjectList;
    }


    /**
     * api: 过滤查询关联表单多选时的数据
     *
     * @return
     */
    private List<Map<String, Object>> filterMultWorkSheet(Page<Map<String, Object>> queryData, List<Map<String, String>> filter) {
        List<Map<String, Object>> result = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(filter)) {
            for (Map<String, Object> map : queryData.getContent()) {
                for (Map<String, String> m : filter) {
                    for (Map.Entry<String, String> mm : m.entrySet()) {
                        String key = mm.getKey();
                        if (map.get(key) instanceof HashMap) {
                            HashMap str = (HashMap) map.get(key);
                            if (str != null && !Strings.isNullOrEmpty(mm.getValue())) {
                                List<String> list = Arrays.asList(str.get("id").toString().split(";"));
                                List<String> query = Arrays.asList(mm.getValue().split(";"));
                                boolean flag = contrastList(list, query);
                                if (flag) {
                                    result.add(map);
                                }
                            }
                        }
                    }
                }
            }
        } else {
            result.addAll(queryData.getContent());
        }
        return result;
    }

    private boolean contrastList(List<String> list, List<String> query) {
        boolean flag = false;
        int num = 0;
        for (int i = 0; i < list.size(); i++) {
            String str = Optional.ofNullable(list.get(i)).orElse("");
            for (int j = 0; j < query.size(); j++) {
                String s = Optional.ofNullable(query.get(j)).orElse("");
                if (s != "" && str.equals(s)) {
                    num++;
                }
            }
        }
        if (num == query.size()) {
            flag = true;
        }
        return flag;
    }

    private List<Map<String, Object>> getPageList(List<Map<String, Object>> data, int page, int size) {
        Integer pageNo = page * size;
        Integer sum = data.size();
        List<Map<String, Object>> pages = Lists.newArrayList();
        if (pageNo + size > sum) {
            pages = data.subList(pageNo, sum);
        } else {
            pages = data.subList(pageNo, pageNo + size);
        }
        return pages;
    }


    /**
     * 保存列表数据批量修改记录
     *
     * @param bizObjectBatchUpdateRecordModel
     */
    @Override
    public void saveBizObjectBatchUpdateRecord(BizObjectBatchUpdateRecordModel bizObjectBatchUpdateRecordModel) {
        batchUpdateRecordService.saveBizObjectBatchUpdateRecord(ModelUtil.toEntity(bizObjectBatchUpdateRecordModel, BizObjectBatchUpdateRecord.class));
    }

    /**
     * 查询列表数据批量修改记录
     *
     * @param schemaCode
     * @param pageable
     * @return
     */
    @Override
    public org.springframework.data.domain.Page<BizObjectBatchUpdateRecordModel> queryBizObjectBatchUpdateRecord(String schemaCode, org.springframework.data.domain.Pageable pageable) {
        org.springframework.data.domain.Page<BizObjectBatchUpdateRecordModel> page = ModelUtil.toModel(batchUpdateRecordService.queryBizObjectBatchUpdateRecord(schemaCode, pageable), pageable, BizObjectBatchUpdateRecordModel.class);
        List<BizObjectBatchUpdateRecordModel> content = page.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return page;
        }

        List<String> userIds = content.stream().map(BizObjectBatchUpdateRecordModel::getUserId).collect(Collectors.toList());
        List<UserModel> users = userFacade.listByIdList(userIds);
        if (CollectionUtils.isEmpty(users)) {
            return page;
        }

        Map<String, UserModel> userNameMap = users.stream().collect(Collectors.toMap(UserModel::getId, Function.identity(), (v1, v2) -> v1));
        for (BizObjectBatchUpdateRecordModel bizObjectBatchUpdateRecordModel : content) {
            UserModel user = userNameMap.get(bizObjectBatchUpdateRecordModel.getUserId());
            if (user != null) {
                bizObjectBatchUpdateRecordModel.setUserName(user.getName());
                bizObjectBatchUpdateRecordModel.setImgUrl(user.getImgUrl());
            }
        }

        return page;
    }

    @Override
    public void updateBizObject(String userId, BizObjectModel bizObject, BizObject objectExisted) {
        bizObjectService.updateBizObject(userId, bizObject, objectExisted, null);
    }

    @Override
    public void updateBizObject(String userId, BizObjectModel bizObject, BizObject objectExisted, BizObjectOptions options) {
        bizObjectService.updateBizObject(userId, bizObject, objectExisted, options);
    }

    @Override
    public String saveComment(BizCommentModel model) {
        return bizObjectService.saveComment(new CreateComment() {
            @Override
            public String getSchemaCode() {
                return model.getSchemaCode();
            }

            @Override
            public String getBizObjectId() {
                return model.getBizObjectId();
            }

            @Override
            public String getWorkflowTokenId() {
                return model.getWorkflowTokenId();
            }

            @Override
            public String getWorkflowInstanceId() {
                return model.getWorkflowInstanceId();
            }

            @Nullable
            @Override
            public String getWorkItemId() {
                return model.getWorkItemId();
            }

            @Override
            public Integer getTokenId() {
                return model.getTokenId();
            }

            @Override
            public String getActivityCode() {
                return model.getActivityCode();
            }

            @Override
            public String getActivityName() {
                return model.getActivityName();
            }

            @Override
            public ActionType getActionType() {
                return model.getActionType();
            }

            @Override
            public String getContent() {
                return model.getContent();
            }

            @Override
            @Nullable
            public FormActionType getResult() {
                return model.getResult();
            }

            @Override
            @Nullable
            public String getBizPropertyCode() {
                return model.getBizPropertyCode();
            }

            @Override
            @Nullable
            public List<SelectionValue> getRelUsers() {
                if (org.springframework.util.CollectionUtils.isEmpty(model.getRelUsers())) {
                    return Lists.newArrayList();
                }
                String relUser = JSON.toJSONString(model.getRelUsers());
                return JSON.parseObject(relUser, new TypeReference<List<SelectionValue>>() {
                });
            }

            @Override
            public String getCreater() {
                return model.getCreatedBy();
            }

            @Nullable
            @Override
            public List<Attachment> getAttachments() {
                if (org.springframework.util.CollectionUtils.isEmpty(model.getResources())) {
                    return Lists.newArrayList();
                }
                return model.getResources().stream().map(it -> new Attachment() {
                    @Override
                    public String getId() {
                        return it.getId();
                    }

                    @Override
                    public String getRefId() {
                        return it.getRefId();
                    }

                    @Override
                    public String getName() {
                        return it.getName();
                    }

                    @Override
                    public String getMimeType() {
                        return it.getMimeType();
                    }

                    @Override
                    public String getFileExtension() {
                        return it.getFileExtension();
                    }

                    @Override
                    public Integer getFileSize() {
                        return it.getFileSize();
                    }

                    @Override
                    public String getBase64ImageStr() {
                        return it.getBase64ImageStr();
                    }
                }).collect(Collectors.toList());
            }
        });
    }

    @Override
    public BizObject loadBizObject(String schemaCode, @Nullable String objectId, @Nullable Map<String, Object> data) {
        return bizObjectService.loadBizObject(schemaCode, objectId, data);
    }

    @Override
    public BizObject createAndGetBizObject(String userId, BizObjectModel bizObject) throws EngineRuntimeException, ServiceException {
        return bizObjectService.createAndGetBizObject(userId, bizObject);
    }

    @Override
    public void updateBizObject(BizObject bizObject) throws EngineRuntimeException, ServiceException {
        bizObjectService.updateBizObject(bizObject, null);
    }

    @Override
    public void updateBizObject(BizObject bizObject, BizObjectOptions options) throws EngineRuntimeException, ServiceException {
        bizObjectService.updateBizObject(bizObject, options);
    }

    @Override
    public void deleteBizObject(String schemaCode, String objectId) {
        bizObjectService.deleteBizObject(schemaCode, objectId);
    }

    @Override
    public BizObject invokeBizRule(String schemaCode, String objectId, BizObject bizObject, String businessRuleCode) {
        return bizObjectService.invokeBizRule(schemaCode, objectId, bizObject, businessRuleCode);
    }

    @Override
    public void invokeMethod(BizObject bizObject, String bizSchemaMethodCode) {
        bizObjectService.invokeMethod(bizObject, bizSchemaMethodCode);
    }

    @Override
    public String genBizObjectId() {
        return bizObjectService.genBizObjectId();
    }

    @Override
    public BizObject createAndGetBizObject(BizObject bizObject) throws EngineRuntimeException, ServiceException {
        return bizObjectService.createAndGetBizObject(bizObject);
    }

    @Override
    public void modifiedBizObject(BizObject bizObject) throws EngineRuntimeException, ServiceException {
        bizObjectService.modifiedBizObject(bizObject, null);
    }

    @Override
    public void modifyBizObject(BizObject bizObject, Boolean isGet) {
        bizObjectService.modifyBizObject(bizObject, isGet, null);
    }

    @Override
    public Page doInvokeMethodForCollection(BizObjectQueryObject bizObjectQueryObject, BizMethodMappingModel bizMethodMappingModel) {
        BizMethodMapping bizMethodMapping = ModelUtil.toEntity(bizMethodMappingModel, BizMethodMapping.class);
        return bizObjectService.doInvokeMethodForCollection(bizObjectQueryObject, bizMethodMapping);
    }

    @Override
    public Page<Map<String, Object>> queryBizObjectsWithNoBind(BizObjectQueryObject bizObjectQueryObject) {
        return bizObjectService.queryBizObjectsWithNoBind(bizObjectQueryObject);
    }

    @Override
    public Page<Map<String, Object>> queryBizObjects(BizObjectQueryObject bizObjectQueryObject) {
        return bizObjectService.queryBizObjects(bizObjectQueryObject);
    }

    @Override
    public List<String> queryBizObjectIds(BizObjectQueryObject bizObjectQueryObject) {
        return bizObjectService.queryBizObjectIds(bizObjectQueryObject);
    }

    @Override
    public void deleteObjectWorkFlow(String objectId) {
        bizObjectService.deleteObjectWorkFlow(objectId);
    }

    @Override
    public long countBizObject(String schemaCode) {
        return bizObjectService.countBizObject(schemaCode);
    }

    @Override
    public void invokeMethod(String schemaCode, String objectId, String bizSchemaMethodCode) {
        bizObjectService.invokeMethod(schemaCode, objectId, bizSchemaMethodCode);
    }

    @Override
    public BizObject invokeMethod(BizObject bizObject, BizMethodMappingModel methodMappingModel) {
        BizMethodMapping bizMethodMapping = ModelUtil.toEntity(methodMappingModel, BizMethodMapping.class);
        return bizObjectService.invokeMethod(bizObject, bizMethodMapping);
    }

    @Override
    public Integer insertAttachments(List<AttachmentModel> attachmentModelList) {
        return bizObjectService.insertAttachments(attachmentModelList);
    }

    @Override
    public String createBizObject(BizObject bizObject) throws EngineRuntimeException, ServiceException {
        return bizObjectService.createBizObject(bizObject);
    }

    /**
     * 关联查询
     *
     * @param queryRelationModel 关联查询对象
     * @return 查询列表分页
     */
    @Override
    public Page<BizObjectModel> relationQuery(BizObjectQueryRelationModel queryRelationModel) {
        if (CollectionUtils.isEmpty(queryRelationModel.getSchemaRelations())) {
            throw new ServiceException(ErrCode.UNKNOW_ERROR, "未指定关联模型");
        }
        if (CollectionUtils.isEmpty(queryRelationModel.getDisplayFields())) {
            throw new ServiceException(ErrCode.UNKNOW_ERROR, "未指定查询字段");
        }
        QueryRelationObject queryObject = new QueryRelationObject();
        //主模型编码
        queryObject.setSchemaCode(queryRelationModel.getSchemaCode());
        //关联模型
        queryObject.getSchemaRelationsMap().put(queryRelationModel.getSchemaCode(), queryRelationModel.getSchemaRelations());
        //显示字段
        queryObject.setDisplayFields(queryRelationModel.getDisplayFields());
        //分组字段
        queryObject.setGroupByFields(queryRelationModel.getGroupByFields());
        //排序字段
        queryObject.setOrderByFields(queryRelationModel.getOrderByFields());
        //查询条件
        queryObject.setFilterExpression(queryRelationModel.getFilters());
        //分页信息
        if (queryRelationModel.getPage() != null) {
            Pageable pageable = new PageableImpl(queryRelationModel.getPage() * queryRelationModel.getSize(), queryRelationModel.getSize());
            queryObject.setPageable(pageable);
        }
        Page<Map<String, Object>> pageResult = bizObjectLocalCacheService.relationQuery(queryObject);
        List<BizObjectModel> bizObjectList = new ArrayList<>();
        for (Map<String, Object> map : pageResult.getContent()) {
            BizObjectModel bizObjectModel = new BizObjectModel(queryObject.getSchemaCode(), map, false);
            bizObjectList.add(bizObjectModel);
        }
        if (log.isTraceEnabled()) {
            log.trace("==================bizObjectList={}", JSON.toJSONString(bizObjectList));
        }
        return new PageImpl<>(pageResult.getTotal(), bizObjectList);
    }

    /**
     * 构建多模型查询条件，为空则不是多模型查询
     *
     * @param bizObjectQueryModel 查询信息
     * @param queryId             查询编号
     * @param schemaCode          模型编码
     * @param clientType          客户端
     * @param sorts               排序字段
     * @param properties          数据项
     * @return QueryRelationObject
     **/
    private QueryRelationObject buildRelationQueryObject(BizObjectQueryModel bizObjectQueryModel, String queryId, String schemaCode,
                                                         ClientType clientType, List<BizQuerySort> sorts, List<BizProperty> properties) {
        //1***判断是否需要关联查询
        BizQueryPresent bizQueryPresent = bizQueryPresentService.getByQueryIdAndClientType(queryId, clientType);
        if (bizQueryPresent == null) {
            return null;
        }
        String schemaRelationsJson = bizQueryPresent.getSchemaRelations();
        if (StringUtils.isBlank(schemaRelationsJson)) {
            return null;
        }
        BizQuerySchemaRelationModel bizQuerySchemaRelationModel = JSONUtil.toBean(schemaRelationsJson, BizQuerySchemaRelationModel.class);
        if (bizQuerySchemaRelationModel == null) {
            return null;
        }
        Map<String, String> aliasMapping = bizQuerySchemaRelationModel.getAliasMapping();
        Map<String, List<RelationObject>> schemaRelations = bizQuerySchemaRelationModel.getSchemaRelations();
        if (MapUtils.isEmpty(schemaRelations) || MapUtils.isEmpty(aliasMapping)) {
            return null;
        }
        // 过滤不存在的模型
        Set<String> schemaCodes = Sets.newHashSetWithExpectedSize(aliasMapping.size());
        aliasMapping.values().stream().filter(StringUtils::isNotBlank).forEach(it -> {
            String[] split = it.split("\\.");
            schemaCodes.add(split[0]);
            if (split.length > 1) {
                schemaCodes.add(split[1]);
            }
        });

        List<BizSchema> bizSchemas = bizSchemaService.findByCodeIn(Lists.newArrayList(schemaCodes), true, false);
        if (CollectionUtils.isEmpty(bizSchemas)) {
            log.error("[relation query] build query object, bizSchemas is null, return.");
            return null;
        }

        List<BizQueryColumn> bizQueryColumns = bizQueryColumnService.getListByQueryId(queryId, clientType);
        //过滤数据项中不存在的字段
        bizQueryColumnService.filterBizQueryColumn(schemaCode, bizQueryColumns, clientType, aliasMapping);

        if (bizSchemas.size() < schemaCodes.size()) {
            Set<String> bizSchemaCodes = bizSchemas.stream().map(BizSchema::getCode).collect(Collectors.toSet());
            schemaCodes.removeAll(bizSchemaCodes);
            Set<String> notExistAlias = Sets.newHashSetWithExpectedSize(schemaCodes.size());
            log.debug("[relation query] build query object, remove not exist model from schemaRelations, notExistAlias={}.", notExistAlias);
            aliasMapping.forEach((k, v) -> {
                String[] split = v.split("\\.");
                if (!schemaCodes.contains(split[0])) {
                    return;
                }
                if (split.length > 1 && !schemaCodes.contains(split[1])) {
                    return;
                }
                notExistAlias.add(k);
                schemaRelations.remove(v);
            });
            schemaRelations.forEach((k, v) -> {
                List<RelationObject> relationObjects = Lists.newArrayListWithExpectedSize(v.size());
                for (RelationObject r : v) {
                    HashSet<Object> onSchemaAlias = Sets.newHashSetWithExpectedSize(r.getOn().size() * 2);
                    onSchemaAlias.addAll(r.getOn().stream().map(RelationObject.On::getLeftSchemaAlias).collect(Collectors.toSet()));
                    onSchemaAlias.addAll(r.getOn().stream().map(RelationObject.On::getRightSchemaAlias).collect(Collectors.toSet()));
                    if (CollectionUtils.intersection(onSchemaAlias, notExistAlias).size() > 0) {
                        notExistAlias.add(r.getSchemaAlias());
                        continue;
                    }
                    relationObjects.add(r);
                }
                schemaRelations.put(k, relationObjects);
            });
            if (CollectionUtils.isEmpty(schemaRelations.get(schemaCode))) {
                log.error("[relation query] build query object, there is not relation model after remove not exist.");
                return null;
            }
            aliasMapping.keySet().removeIf(notExistAlias::contains);
            bizQueryColumns.removeIf(it -> !aliasMapping.containsKey(it.getSchemaAlias()));
        }


        List<BizQueryColumn> mainQueryColumns = bizQueryColumns.stream().filter(it -> Objects.equals(QueryLevelType.MAIN.getType(), it.getQueryLevel())).collect(Collectors.toList());

        //主表存在待显示的被关联字段
        boolean mainExistRelation = mainQueryColumns.stream().anyMatch(it -> !schemaCode.equals(it.getSchemaCode()));
        //子表存在待显示的被关联字段
        boolean childExistRelation = false;

        //判断子表字段是否选择显示了关联字段
        List<BizQueryColumn> mainChildQueryColumns = mainQueryColumns.stream().filter(it -> BizPropertyType.CHILD_TABLE.equals(it.getPropertyType())).collect(Collectors.toList());
        for (BizQueryColumn childQueryColumn : mainChildQueryColumns) {
            childExistRelation = bizQueryColumns.stream().anyMatch(it ->
                    QueryLevelType.CHILD.getType().equals(it.getQueryLevel()) && childQueryColumn.getPropertyCode().equals(it.getSchemaCode()) && !childQueryColumn.getPropertyAlias().equals(it.getSchemaAlias()));
            if (childExistRelation) {
                break;
            }
        }

        if (!mainExistRelation && !childExistRelation) {
            return null;
        }

        //2***组装关联查询的条件
        QueryRelationObject queryObject = new QueryRelationObject();
        //主模型编码
        queryObject.setSchemaCode(schemaCode);
        queryObject.setSchemaAlias(ModelConstant.MUlIT_MODEL_QUERY_MAIN_DEFAULT_ALIAS);
        //关联模型-关联关系
        queryObject.setSchemaRelationsMap(schemaRelations);
        queryObject.setAliasMapping(aliasMapping);
        //显示字段
        List<DisplayField> displayFields = new ArrayList<>();
        for (BizQueryColumn queryColumn : bizQueryColumns) {
            displayFields.add(DisplayField.builder()
                    .schemaCode(queryColumn.getSchemaCode()).propertyCode(queryColumn.getPropertyCode())
                    .schemaAlias(queryColumn.getSchemaAlias()).propertyAlias(queryColumn.getPropertyAlias())
                    .queryLevel(queryColumn.getQueryLevel())
                    .build());

        }
        queryObject.setDisplayFields(displayFields);
        //主表字段 propertyAlias -> [schemaCode, schemaAlias, propertyCode] 映射关系
        Map<String, List<String>> alias2codeMap = mainQueryColumns.stream().filter(it -> !BizPropertyType.CHILD_TABLE.equals(it.getPropertyType()))
                .collect(Collectors.toMap(BizQueryColumn::getPropertyAlias,
                        v -> Arrays.asList(v.getSchemaCode(), v.getSchemaAlias(), v.getPropertyCode()), (k1, k2) -> k1));
        //展示字段中没有 查询条件中有的字段 为主模型字段
        alias2codeMap.put(null, Arrays.asList(schemaCode, ModelConstant.MUlIT_MODEL_QUERY_MAIN_DEFAULT_ALIAS, null));

        //排序字段
        queryObject.setOrderByFields(resolveSorts(sorts, schemaCode, queryObject.getSchemaAlias(), alias2codeMap));
        //分页信息
        queryObject.setPageable(bizObjectQueryModel.getPageable());
        //分组字段
//        queryObject.setGroupByFields();

        // 使用树形控件作为查询条件
        Triple<Map<String, BizObjectQueryModel.Filter>, List<BizQueryCondition>, Map<String, String>> queryBaseInfo = buildRelationQueryBaseInfoForTree(bizObjectQueryModel, queryId, clientType, properties);
        Map<String, QueryRelationFilter.Item> relationFilterMap = new HashMap<>();
        if (queryBaseInfo != null) {
            Pair<List<RelationObject>, Map<String, QueryRelationFilter.Item>> queryInfo = buildRelationQueryInfoForTree(ModelConstant.MUlIT_MODEL_QUERY_MAIN_DEFAULT_ALIAS, queryBaseInfo);
            relationFilterMap = queryInfo.getRight();
            List<RelationObject> relationObjects = queryInfo.getLeft();
            if (CollectionUtils.isNotEmpty(relationObjects)) {
                queryObject.getSchemaRelationsMap().get(schemaCode).addAll(relationObjects);
            }
        }
        //查询条件
        QueryRelationFilter queryRelationFilter = resolveFilter(bizObjectQueryModel.getFilterExpr(), relationFilterMap, alias2codeMap);
        queryObject.setFilterExpression(queryRelationFilter);

        return queryObject;
    }

    private Triple<Map<String, BizObjectQueryModel.Filter>, List<BizQueryCondition>, Map<String, String>> buildRelationQueryBaseInfoForTree(BizObjectQueryModel bizObjectQueryModel,
                                                                                                                                            String queryId, ClientType clientType, List<BizProperty> properties) {

        /* 1.拦截校验 */
        if (CollectionUtils.isEmpty(bizObjectQueryModel.getFilters())) {
            return null;
        }

        List<BizObjectQueryModel.Filter> workSheetFilters = bizObjectQueryModel.getFilters().stream().filter(it -> CollectionUtils.isNotEmpty(it.getPropertyValue())).collect(Collectors.toList());
        // 判断 存在的查询条件
        if (CollectionUtils.isEmpty(workSheetFilters)) {
            return null;
        }

        List<BizQueryCondition> queryConditions = bizQueryConditionService.getListByQueryId(queryId, clientType);
        // 有[包含字数]的查询条件
        Map<String, BizObjectQueryModel.Filter> workSheetFilterMap = workSheetFilters.stream().collect(Collectors.toMap(BizObjectQueryModel.Filter::getPropertyCode, Function.identity(), (k1, k2) -> k1));
        List<BizQueryCondition> queryConditionForRelation = queryConditions.stream()
                .filter(it -> BizPropertyType.WORK_SHEET == it.getPropertyType() && it.getIncludeSubData() && workSheetFilterMap.containsKey(it.getPropertyCode()))
                .collect(Collectors.toList());
        // 判断 存在需要嵌套查询的条件配置
        if (CollectionUtils.isEmpty(queryConditionForRelation)) {
            return null;
        }

        Map<String, String> codeToRelationSchemaCodeMap = properties.stream()
                .filter(it -> BizPropertyType.WORK_SHEET == it.getPropertyType() && StringUtils.isNotBlank(it.getRelativeCode()) && workSheetFilterMap.containsKey(it.getCode()))
                .collect(Collectors.toMap(BizProperty::getCode, BizProperty::getRelativeCode, (k1, k2) -> k1));
        // 判断 关联模型数据项是否存在
        if (MapUtils.isEmpty(codeToRelationSchemaCodeMap)) {
            return null;
        }

        Map<String, List<BizProperty>> relationPropertyMap = bizPropertyService.findMapBySchemaCodeIn(new ArrayList<>(codeToRelationSchemaCodeMap.values()), true, false);
        if (MapUtils.isEmpty(relationPropertyMap)) {
            return null;
        }

        return Triple.of(workSheetFilterMap, queryConditionForRelation, codeToRelationSchemaCodeMap);
    }

    private Pair<List<RelationObject>, Map<String, QueryRelationFilter.Item>> buildRelationQueryInfoForTree(String mainSchemaAlias, Triple<Map<String, BizObjectQueryModel.Filter>, List<BizQueryCondition>, Map<String, String>> treeRelationQueryBaseInfo) {

        Map<String, BizObjectQueryModel.Filter> workSheetFilterMap = treeRelationQueryBaseInfo.getLeft();
        List<BizQueryCondition> queryConditionForRelation = treeRelationQueryBaseInfo.getMiddle();
        Map<String, String> codeToRelationSchemaCodeMap = treeRelationQueryBaseInfo.getRight();

        List<RelationObject> relationObjects = new ArrayList<>();
        Map<String, QueryRelationFilter.Item> relationFilterMap = new HashMap<>();

        queryConditionForRelation.forEach(it -> {
            String relationSchemaCode = codeToRelationSchemaCodeMap.get(it.getPropertyCode());
            RelationObject relationObject = new RelationObject();
            relationObject.setSchemaCode(relationSchemaCode);
            relationObject.setSchemaAlias(relationSchemaCode);
            relationObject.setJoinType(RelationObject.JoinType.LEFT);
            relationObject.setQueryLevel(QueryLevelType.MAIN.getType());
            RelationObject.On on = new RelationObject.On();
            on.setLeftSchemaAlias(relationSchemaCode);
            on.setLeftPropertyCode(DefaultPropertyType.ID.getCode());
            on.setRightSchemaAlias(mainSchemaAlias);
            on.setRightPropertyCode(it.getPropertyCode());
            relationObject.setOn(Collections.singletonList(on));

            BizObjectQueryModel.Filter filter = workSheetFilterMap.get(it.getPropertyCode());
            BizObject bizObject = bizObjectService.loadBizObject(relationSchemaCode, filter.getPropertyValue().get(0), null);
            if (bizObject == null) {
                return;
            }
            String path = (String) bizObject.getData().get(DefaultTreePropertyType.PATH.getCode());
            if (StringUtils.isBlank(path)) {
                return;
            }
            relationObjects.add(relationObject);
            relationFilterMap.put(it.getPropertyCode(), new QueryRelationFilter.Item(relationSchemaCode, relationSchemaCode, DefaultTreePropertyType.PATH.getCode(), FilterExpression.Op.LLike, path));
        });
        return Pair.of(relationObjects, relationFilterMap);
    }

    /**
     * 构建多模型查询条件，为空则不是多模型查询 - 使用树形控件作为查询条件时使用
     *
     * @param bizObjectQueryModel 查询信息
     * @param queryId             查询条件id
     * @param clientType          客户端
     * @param properties          数据项
     * @return QueryRelationObject
     **/
    private QueryRelationObject buildRelationQueryObjectForTree(BizObjectQueryModel bizObjectQueryModel, String queryId, ClientType clientType,
                                                                List<BizQuerySort> sorts, List<BizProperty> properties) {

        Triple<Map<String, BizObjectQueryModel.Filter>, List<BizQueryCondition>, Map<String, String>> queryBaseInfo = buildRelationQueryBaseInfoForTree(bizObjectQueryModel, queryId, clientType, properties);
        if (queryBaseInfo == null) {
            return null;
        }

        /* 2.构建多模型查询信息 */
        String schemaCode = bizObjectQueryModel.getSchemaCode();
        QueryRelationObject queryObject = new QueryRelationObject();
        //主模型编码
        queryObject.setSchemaCode(schemaCode);
        queryObject.getAliasMapping().put(schemaCode, schemaCode);

        List<BizQueryColumn> queryColumns = bizQueryColumnService.getListByQueryId(queryId, clientType);
        Map<String, List<BizQueryColumn>> queryColumnMap = queryColumns.stream().filter(it -> !BooleanUtil.isTrue(it.getDeleted())).collect(Collectors.groupingBy(BizQueryColumn::getSchemaCode));

        //显示字段 - 主表  移除主表查询信息
        List<DisplayField> displayFields = new ArrayList<>();
        List<String> bizPropertyCodes = getPropertyCodes(properties);
        List<BizQueryColumn> mainQueryColumns = queryColumnMap.remove(schemaCode);
        if (CollectionUtils.isEmpty(mainQueryColumns)) {
            return null;
        }
        mainQueryColumns.stream().filter(it -> bizPropertyCodes.contains(it.getPropertyCode())).forEach(it -> {
            displayFields.add(DisplayField.builder()
                    .schemaCode(schemaCode).propertyCode(it.getPropertyCode()).queryLevel(QueryLevelType.MAIN.getType())
                    .build());
        });

        //显示字段 - 子表
        List<DisplayField> childDisplays = buildChildDisplayField(queryColumnMap, properties);
        if (CollectionUtils.isNotEmpty(childDisplays)) {
            displayFields.addAll(childDisplays);
        }
        queryObject.setDisplayFields(displayFields);

        Pair<List<RelationObject>, Map<String, QueryRelationFilter.Item>> queryInfo = buildRelationQueryInfoForTree(schemaCode, queryBaseInfo);
        Map<String, QueryRelationFilter.Item> relationFilterMap = queryInfo.getRight();
        if (relationFilterMap.isEmpty()) {
            log.error("[tree relation query] relationFilterMap is null, return.");
            return null;
        }
        List<RelationObject> relationObjects = queryInfo.getLeft();

        //构建查询条件
        Map<String, List<String>> alias2codeMap = new HashMap<>();
        alias2codeMap.put(null, Arrays.asList(schemaCode, schemaCode, null));
        QueryRelationFilter queryRelationFilter = resolveFilter(bizObjectQueryModel.getFilterExpr(), relationFilterMap, alias2codeMap);
        queryObject.setFilterExpression(queryRelationFilter);

        //构建连表查询关联关系
        queryObject.getSchemaRelationsMap().put(schemaCode, relationObjects);
        //排序字段
        queryObject.setOrderByFields(resolveSorts(sorts, schemaCode, queryObject.getSchemaAlias(), alias2codeMap));
        //分组字段
//        queryObject.setGroupByFields();
        //分页信息
        queryObject.setPageable(bizObjectQueryModel.getPageable());
        return queryObject;
    }

    private List<DisplayField> buildChildDisplayField(Map<String, List<BizQueryColumn>> queryColumnMap, List<BizProperty> properties) {

        if (MapUtils.isEmpty(queryColumnMap)) {
            return null;
        }
        List<String> childSchemaCodes = properties.stream().filter(it -> BizPropertyType.CHILD_TABLE == it.getPropertyType()).map(BizProperty::getCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(childSchemaCodes)) {
            return null;
        }
        Map<String, List<BizProperty>> childPropertyMap = bizPropertyService.findMapBySchemaCodeIn(childSchemaCodes, true, false);
        if (MapUtils.isEmpty(childPropertyMap)) {
            return null;
        }
        List<DisplayField> displayFields = new ArrayList<>();
        queryColumnMap.forEach((k, v) -> {
            List<BizProperty> bizProperties = childPropertyMap.get(k);
            if (CollectionUtils.isEmpty(bizProperties)) {
                return;
            }
            List<String> propertyCodes = getPropertyCodes(bizProperties);
            v.stream().filter(c -> propertyCodes.contains(c.getPropertyCode())).forEach(c -> displayFields.add(DisplayField.builder()
                    .schemaCode(c.getSchemaCode()).propertyCode(c.getPropertyCode()).queryLevel(QueryLevelType.CHILD.getType())
                    .build()));
        });
        return displayFields;
    }

    private List<String> getPropertyCodes(List<BizProperty> properties) {
        return properties.stream().map(BizProperty::getCode).collect(Collectors.toList());
    }

    /**
     * 关联查询-排序条件
     *
     * @param sorts       已组装好的查询条件
     * @param schemaCode  主模型编码
     * @param schemaAlias 主模型别名
     * @return List
     **/
    private List<OrderByField> resolveSorts(List<BizQuerySort> sorts, String schemaCode, String schemaAlias, Map<String, List<String>> alias2codeMap) {
        List<OrderByField> sortList = new ArrayList<>();
        if (CollectionUtils.isEmpty(sorts)) {
            sortList.add(new OrderByField(schemaCode, schemaAlias, DefaultPropertyType.CREATED_TIME.getCode(), Order.Dir.DESC));
        } else {
            sorts.forEach(it -> {
                List<String> info = alias2codeMap.get(it.getPropertyCode());
                sortList.add(new OrderByField(it.getSchemaCode(), (info == null ? it.getSchemaCode() : info.get(1)), it.getPropertyCode(),
                        SortDirectionType.ASC.equals(it.getDirection()) ? Order.Dir.ASC : Order.Dir.DESC));
            });
        }
        return sortList;
    }

    /**
     * 关联查询-过滤条件 从组装好的查询条件转换为关联查询条件
     *
     * @param filter 已组装好的查询条件
     * @return QueryRelationFilter
     **/
    private QueryRelationFilter resolveFilter(FilterExpression filter, Map<String, QueryRelationFilter.Item> waitReplaceFilters, Map<String, List<String>> alias2codeMap) {
        if (filter == null) {
            return null;
        }
        if (filter instanceof FilterExpression.Item) {
            return resolveFilter((FilterExpression.Item) filter, waitReplaceFilters, alias2codeMap);
        } else if (filter instanceof FilterExpression.Or) {
            return resolveFilter((FilterExpression.Or) filter, waitReplaceFilters, alias2codeMap);
        } else if (filter instanceof FilterExpression.And) {
            return resolveFilter((FilterExpression.And) filter, waitReplaceFilters, alias2codeMap);
        } else {
            return null;
        }
    }

    private QueryRelationFilter resolveFilter(FilterExpression.And and, Map<String, QueryRelationFilter.Item> waitReplaceFilters, Map<String, List<String>> alias2codeMap) {
        List<QueryRelationFilter> result = new ArrayList<>();
        for (FilterExpression item : and.items) {
            if (item instanceof FilterExpression.Item) {
                result.add(resolveFilter((FilterExpression.Item) item, waitReplaceFilters, alias2codeMap));
            } else if (item instanceof FilterExpression.Or) {
                result.add(resolveFilter((FilterExpression.Or) item, waitReplaceFilters, alias2codeMap));
            } else if (item instanceof FilterExpression.And) {
                result.add(resolveFilter((FilterExpression.And) item, waitReplaceFilters, alias2codeMap));
            }
        }
        return new QueryRelationFilter.And(result);
    }

    private QueryRelationFilter resolveFilter(FilterExpression.Or or, Map<String, QueryRelationFilter.Item> waitReplaceFilters, Map<String, List<String>> alias2codeMap) {
        List<QueryRelationFilter> result = new ArrayList<>();
        for (FilterExpression item : or.items) {
            if (item instanceof FilterExpression.Item) {
                result.add(resolveFilter((FilterExpression.Item) item, waitReplaceFilters, alias2codeMap));
            } else if (item instanceof FilterExpression.Or) {
                result.add(resolveFilter((FilterExpression.Or) item, waitReplaceFilters, alias2codeMap));
            } else if (item instanceof FilterExpression.And) {
                result.add(resolveFilter((FilterExpression.And) item, waitReplaceFilters, alias2codeMap));
            }
        }
        return new QueryRelationFilter.Or(result);
    }

    private QueryRelationFilter resolveFilter(FilterExpression.Item item, Map<String, QueryRelationFilter.Item> waitReplaceFilters, Map<String, List<String>> alias2codeMap) {
        // 替换 使用树形控件且包含子数据查询时使用
        if (waitReplaceFilters != null) {
            QueryRelationFilter.Item relationItem = waitReplaceFilters.get(item.field);
            if (relationItem != null) {
                return relationItem;
            }
        }
        List<String> info = alias2codeMap.get(item.field);
        if (info == null) {
            info = alias2codeMap.get(null);
        }
        return new QueryRelationFilter.Item(info.get(0), info.get(1), info.get(2) == null ? item.field : info.get(2), item.op, item.value);
    }

    @Override
    public Map<Boolean, Set<String>> checkDataExist(String schemaCode, List<String> ids) {
        if (StringUtils.isEmpty(schemaCode) || CollectionUtils.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        return bizObjectConverter.checkDataExist(schemaCode, ids);
    }

    @Override
    public List<Map<String, Object>> batchCheckTreeCircularRef(List<Map<String, Object>> data, String schemaCode) {
        return bizObjectConverter.batchCheckTreeCircularRef(data, schemaCode);
    }

    @Override
    public List<String> getAllTreeParentIds(String schemaCode, String objectId) {
        return bizObjectConverter.getAllTreeParentIds(schemaCode, objectId);
    }

    @Override
    public boolean compareObject(Object oldValue, Object newValue, BizPropertyType propertyType) {
        return bizObjectService.compareObject(oldValue, newValue, propertyType);
    }

    @Override
    public Page<BizObjectModel> queryBizObjects(String userId, QueryDataModel queryData, Boolean isExport, Boolean isAuthFilter, Boolean isOwner) {
        boolean isMobile = queryData.getMobile();
        ClientType clientType = isMobile ? ClientType.APP : ClientType.PC;
        if (StringUtils.isBlank(queryData.getQueryCode())) {
            queryData.setQueryCode(getQueryCodeFromQuery(queryData.getSchemaCode(), isMobile));
        }
        String schemaCode = queryData.getSchemaCode();
        BizQueryModel bizQueryModel = bizQueryFacade.getBizQuery(schemaCode, queryData.getQueryCode(), clientType, null);
        //生成查询条件方法
        List<FilterModel> filters = queryData.getFilters();
        //过滤关联表单多选查询条件
        List<FilterModel> query = filters.stream().filter(item -> BizPropertyType.MULT_WORK_SHEET != item.getPropertyType()).collect(Collectors.toList());
        queryData.setFilters(query);
        BizObjectQueryModel bizObjectQueryModel = getBizObjectQuery(userId, queryData, bizQueryModel, isAuthFilter, isOwner);
        //过滤关联表单多选
        List<FilterModel> filterVOS = filters.stream().filter(item -> BizPropertyType.MULT_WORK_SHEET == item.getPropertyType()).collect(Collectors.toList());
        List<Map<String, String>> filterStr = Lists.newArrayList();
        for (FilterModel vo : filterVOS) {
            if (StringUtils.isNotEmpty(vo.getPropertyValue())) {
                Map<String, String> map = Maps.newHashMap();
                map.put(vo.getPropertyCode(), vo.getPropertyValue());
                filterStr.add(map);
            }
        }
        //分页信息
        int page = queryData.getPage() == null ? 0 : queryData.getPage();

        int size = queryData.getSize();
        PageableImpl pageable;
        if (isExport) {
            pageable = new PageableImpl(0, size);
        } else if (!CollectionUtils.isEmpty(filterStr)) {
            //当为关联表单多选时，不用PageableImpl作分页
            pageable = null;
        } else {
            pageable = new PageableImpl(page * size, size);
        }

        bizObjectQueryModel.setPageable(pageable);
        bizObjectQueryModel.setSchemaCode(queryData.getSchemaCode());
        bizObjectQueryModel.setQueryCode(queryData.getQueryCode());
        bizObjectQueryModel.setOptions(queryData.getOptions());
        bizObjectQueryModel.setClientType(clientType);
        bizObjectQueryModel.setDisplay(queryData.getDisplay());
        bizObjectQueryModel.setOrderByFields(queryData.getOrderByFields());
        bizObjectQueryModel.setOrderType(queryData.getOrderType());
        bizObjectQueryModel.setView(queryData.getView());

        BizObjectQueryModel bizObjectQuery = parseQueries(bizObjectQueryModel, schemaCode);

        //关联表单展示字段
        QueryDataModel.ReverseSchemaParam param = queryData.getReverseSchemaParam();
        if (param != null && queryData.getReverseViewFlag()) {
            BizObjectQueryModel.Options options = bizObjectQuery.getOptions();
            if (options != null && options.getQueryDisplayType() == QueryDisplayType.APPEND) {
                List<String> addColumnList = getRelevanceFormConfigColumn(param.getReverseSchemaCode(), param.getReverseSheetCode(), param.getReverseRelevanceFormCode());
                List<String> customDisplayColumns = bizObjectQuery.getOptions().getCustomDisplayColumns();
                if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(customDisplayColumns)) {
                    customDisplayColumns.addAll(addColumnList);
                } else {
                    bizObjectQuery.getOptions().setCustomDisplayColumns(addColumnList);
                }
            }

        }

        //原始查询条件
        bizObjectQuery.setFilters(BeanUtil.copyToList(filters, BizObjectQueryModel.Filter.class));

        Page<BizObjectModel> data = this.queryBizObjectsFilter(bizObjectQuery, filterStr, page, size);
        if (CollectionUtils.isNotEmpty(data.getContent())) {
            List<BizQueryColumnModel> bizQueryColumnModels = bizQueryModel.getQueryColumns();
            parseAddressAndReference(data, bizQueryColumnModels, isExport, queryData.getQueryCode());
            if (isMobile) {
                //处理移动端用户图像
                disposeUserInfo(data);
            } else {
                //处理PC端选人
                parseSpecialProperties(data, isExport);
            }
        }
        return data;
    }

    @Override
    public Page<BizObjectModel> queryBizObjectsForRelation(String userId, QueryDataModel queryData, Boolean isExport, Boolean isAuthFilter, Boolean isOwner) {
        log.info("----------1------------");
        Boolean isMobile = Objects.nonNull(queryData.getMobile()) ? queryData.getMobile() : Boolean.FALSE;
        ClientType clientType = isMobile ? ClientType.APP : ClientType.PC;
        if (StringUtils.isEmpty(queryData.getQueryCode())) {
            queryData.setQueryCode(getQueryCodeFromQuery(queryData.getSchemaCode(), isMobile));
        }
        BizQueryModel bizQueryModel = bizQueryFacade.getBizQuery(queryData.getSchemaCode(), queryData.getQueryCode(), clientType, null);
        //生成查询条件方法
        BizObjectQueryModel bizObjectQueryModel = getBizObjectQueryForRelation(userId, queryData, bizQueryModel, isAuthFilter, isOwner);
        //分页信息
        int page = queryData.getPage() == null ? 0 : queryData.getPage();
        int size = queryData.getSize();
        PageableImpl pageable = null;
        if (isExport) {
            pageable = new PageableImpl(0, size);
        } else {
            pageable = new PageableImpl(page * size, size);
        }

        bizObjectQueryModel.setPageable(pageable);
        bizObjectQueryModel.setSchemaCode(queryData.getSchemaCode());
        bizObjectQueryModel.setQueryCode(queryData.getQueryCode());
        bizObjectQueryModel.setOptions(queryData.getOptions());
        bizObjectQueryModel.setClientType(clientType);

        bizObjectQueryModel.setDisplay(queryData.getDisplay());
        log.info("bizObjectQueryModel：{}",bizObjectQueryModel);
        Page<BizObjectModel> data = this.queryBizObjects(bizObjectQueryModel);

        if (CollectionUtils.isNotEmpty(data.getContent())) {
            List<BizQueryColumnModel> bizQueryColumnModels = bizQueryModel.getQueryColumns();
            parseAddressAndReference(data, bizQueryColumnModels, isExport, queryData.getQueryCode());
            if (isMobile) {
                //处理移动端用户图像
                disposeUserInfo(data);
            } else {
                //处理PC端选人
                parseSpecialProperties(data, isExport);
            }
        }
        return data;
    }

    @Override
    public String getQueryCodeFromQuery(String schemaCode, boolean isMobile) {
        List<BizQueryHeaderModel> bizQueryHeaders = Lists.newArrayList();
        //如果列表编码为空则获取默认第一个列表
        List<BizQueryHeaderModel> bizQueryHeadersTmp = bizQueryFacade.getBizQueryHeaders(schemaCode);
        List<BizQueryHeaderModel> bizQueryHeadersForApp = bizQueryHeadersTmp.stream().filter(t -> Objects.equals(t.getShowOnMobile(), Boolean.TRUE)).collect(Collectors.toList());
        List<BizQueryHeaderModel> bizQueryHeadersForPC = bizQueryHeadersTmp.stream().filter(t -> Objects.equals(t.getShowOnPc(), Boolean.TRUE)).collect(Collectors.toList());
        if (isMobile) {
            //处理历史数据
            if (CollectionUtils.isNotEmpty(bizQueryHeadersForApp)) {
                bizQueryHeaders.addAll(bizQueryHeadersForApp);
            }
        } else {
            bizQueryHeaders.addAll(bizQueryHeadersForPC);
        }
        return CollectionUtils.isNotEmpty(bizQueryHeaders) ? bizQueryHeaders.get(0).getCode() : bizQueryHeadersTmp.get(0).getCode();
    }

    @Override
    public BizObjectQueryModel getBizObjectQuery(String userId, QueryDataModel queryDataVO, BizQueryModel bizQueryModel, Boolean isAuthFilter, Boolean isOwner, boolean isRelation) {
        if (isRelation) {
            return this.getBizObjectQueryForRelation(userId, queryDataVO, bizQueryModel, isAuthFilter, isOwner);
        } else {
            return this.getBizObjectQuery(userId, queryDataVO, bizQueryModel, isAuthFilter, isOwner);
        }

    }

    private BizObjectQueryModel getBizObjectQuery(String userId, QueryDataModel queryDataVO, BizQueryModel bizQueryModel, Boolean isAuthFilter, Boolean isOwner) {

        //权限条件
        FilterExpression authFilter = isAuthFilter ? getAuthFilter(queryDataVO, userId, isOwner) : FilterExpression.empty;
        if (log.isDebugEnabled()) {
            log.debug(JSON.toJSONString(authFilter));
        }

        //树形控件添加默认条件
        ModelViewQueryModel view = queryDataVO.getView();
        if (view != null && ModelViewType.TREE == view.getType()) {
            if (queryDataVO.getFilters().stream().anyMatch(it -> !DefaultTreePropertyType.PARENT_REF.getCode().equals(it.getPropertyCode()) && CollectionUtils.isNotEmpty(it.getPropertyValueList()))) {
                //树形模型 存在查询条件时 存个标记
                view.setExistQueryCondition(true);
            } else {
                FilterModel parentRefFilter = queryDataVO.getFilters().stream().filter(it -> DefaultTreePropertyType.PARENT_REF.getCode().equals(it.getPropertyCode()) && CollectionUtils.isNotEmpty(it.getPropertyValueList())).findAny().orElse(null);
                if (parentRefFilter != null) {
                    view.setParentRef(parentRefFilter.getPropertyValueList().get(0));
                    queryDataVO.getFilters().remove(parentRefFilter);
                }
                if (StringUtils.isBlank(view.getParentRef())) {
                    //无查询条件 parentRef为空时 默认从根节点查询
                    view.setParentRef(ModelViewQueryModel.TREE_QUERY_ROOT_PARENT_REF);
                } else {
                    // 懒加载时，多查一层
                    if (view.getDepth() > 0) {
                        view.setDepth(view.getDepth() + 1);
                    }
                }
            }
        }

        //生成查询条件
        FilterExpression finalFilterExpr = getFilterList(queryDataVO.getFilters(), bizQueryModel.getQueryConditions(), queryDataVO.isCustomizedQuery());

        //生成选中的列表的查询条件
        FilterExpression checkedFilter = getCheckedFilters(queryDataVO.getObjectIds());
        List<FilterExpression> filterExprs = new ArrayList<>();
        List<FilterExpression> filterExcludeAuth = new ArrayList<>();
        if (!finalFilterExpr.equals(FilterExpression.empty)) {
            filterExprs.add(finalFilterExpr);
            filterExcludeAuth.add(finalFilterExpr);
        }
        if (!checkedFilter.equals(FilterExpression.empty)) {
            filterExprs.add(checkedFilter);
            filterExcludeAuth.add(finalFilterExpr);
        }

        FilterExpression.Or statusFilters = this.filterSeqStatus(userId);
        filterExprs.add(statusFilters);
        filterExcludeAuth.add(statusFilters);

        if (!Objects.equals(authFilter, FilterExpression.empty)) {
            filterExprs.add(authFilter);
        }

        BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();

        bizObjectQueryObject.setFilterExpr(filterExprs.size() > 1 ? Q.and(filterExprs) : filterExprs.get(0));
        bizObjectQueryObject.setFilterExcludeAuth(filterExcludeAuth.size() > 1 ? Q.and(filterExcludeAuth) : filterExcludeAuth.get(0));
        bizObjectQueryObject.setAuthFilter(authFilter);
        if (log.isDebugEnabled()) {
            log.debug("列表查询条件为{}", JSONUtil.toJsonStr(bizObjectQueryObject.getFilterExpr()));
        }
        bizObjectQueryObject.setView(queryDataVO.getView());
        bizObjectQueryObject.setSchemaCode(bizQueryModel.getSchemaCode());
        bizObjectQueryObject.setClientType(Objects.nonNull(queryDataVO.getMobile()) && queryDataVO.getMobile() ? ClientType.APP : ClientType.PC);
        return bizObjectQueryObject;
    }

    private FilterExpression getAuthFilter(QueryDataModel queryDataVO, String userId, boolean isOwner) {
        FilterExpression authFilter;
        //是否临时授权
        if (StringUtils.isNotEmpty(queryDataVO.getTempAuthObjectId()) || StringUtils.isNotEmpty(queryDataVO.getTempAuthPropertyCode())) {
            BizFormModel sourceSheet = this.getTempAuthSchemaCodes(queryDataVO.getTempAuthSheetId());
            if (sourceSheet == null) {
                authFilter = permissionManagementFacade.getQueryFilterExpression(userId, queryDataVO.getSchemaCode(), isOwner);
            } else {
                //跳转过来的源表单的临时授权当前访问的表单  与前端约定保存的表单数据为 SchemaCode_SheetCode
                if (sourceSheet.getTempAuthSchemaCodes().contains(queryDataVO.getSchemaCode() + "_")) {
                    authFilter = permissionManagementFacade.getQueryFilterExpression(userId, sourceSheet.getSchemaCode(), isOwner);
                } else {
                    authFilter = permissionManagementFacade.getQueryFilterExpression(userId, queryDataVO.getSchemaCode(), isOwner);
                }
            }
        } else {
            authFilter = permissionManagementFacade.getQueryFilterExpression(userId, queryDataVO.getSchemaCode(), isOwner);
        }
        return authFilter;
    }

    /**
     * 获取关联查询/反关联查询条件对象 TODO 统一入口
     *
     * @param userId        用户id
     * @param queryDataVO   查询数据结果
     * @param bizQueryModel 列表详细信息
     * @return BizObjectQueryModel
     */
    private BizObjectQueryModel getBizObjectQueryForRelation(String userId, QueryDataModel queryDataVO, BizQueryModel bizQueryModel, Boolean isAuthFilter, Boolean isOwner) {
        List<FilterExpression> filterExpressions = new ArrayList<>();
        //权限条件
        FilterExpression authFilter = isAuthFilter ? getAuthFilter(queryDataVO, userId, isOwner) : FilterExpression.empty;
        //生成查询条件
        FilterExpression finalFilterExpr = getFilterList(queryDataVO.getFilters(), bizQueryModel.getQueryConditions(), queryDataVO.isCustomizedQuery());
        log.info("------2------生成查询条件：{}",finalFilterExpr);

        //生成选中的列表的查询条件
        FilterExpression checkedFilter = getCheckedFilters(queryDataVO.getObjectIds());
        if (!authFilter.equals(FilterExpression.empty)) {
            filterExpressions.add(authFilter);
        }
        if (!finalFilterExpr.equals(FilterExpression.empty)) {
            filterExpressions.add(finalFilterExpr);
        }
        if (!checkedFilter.equals(FilterExpression.empty)) {
            filterExpressions.add(checkedFilter);
        }

        //有流程的数据排除模拟流程的数据 SIMULATIVE；没有流程的保留 workflowInstanceId 为空
        List<String> simulates = bizWorkflowInstanceService.findIdListBySchemaCodeAndDataType(queryDataVO.getSchemaCode(), ProcessDataType.SIMULATIVE);
        if (!CollectionUtils.isEmpty(simulates)) {
            FilterExpression.Or or = Q.or(Q.it(DefaultPropertyType.WORKFLOW_INSTANCE_ID.getCode(), FilterExpression.Op.NotIn, simulates),
                    Q.it(DefaultPropertyType.WORKFLOW_INSTANCE_ID.getCode(), FilterExpression.Op.Eq, null));
            filterExpressions.add(or);
        }
        filterExpressions.add(filterSeqStatus(userId));

        BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
        FilterExpression filterExprTemplate = FilterExpression.empty;
        if (filterExpressions.size() > 1) {
            filterExprTemplate = Q.and(filterExpressions);
            if (log.isDebugEnabled()) {
                log.debug("获取的权限相关条件为{}", JSON.toJSONString(filterExprTemplate));
            }
        } else if (filterExpressions.size() == 1) {
            filterExprTemplate = filterExpressions.get(0);
            if (log.isDebugEnabled()) {
                log.debug("获取的权限相关条件为{}", JSON.toJSONString(filterExprTemplate));
            }
        }

        bizObjectQueryObject.setFilterExpr(filterExprTemplate);
        bizObjectQueryObject.setSchemaCode(bizQueryModel.getSchemaCode());
        bizObjectQueryObject.setClientType(Objects.nonNull(queryDataVO.getMobile()) && queryDataVO.getMobile() ? ClientType.APP : ClientType.PC);
        return bizObjectQueryObject;
    }

    @Override
    public Page<BizObjectModel> queryExportData(String userId, QueryDataModel queryData, Boolean isExport, Boolean isAuthFilter, List<BizPropertyModel> properties,
                                                List<BizQueryColumnModel> columns, Map<String, Map<String, Object>> childNumberFormat) {
        long start = System.currentTimeMillis();
        Boolean isMobile = Objects.nonNull(queryData.getMobile()) ? queryData.getMobile() : Boolean.FALSE;
        ClientType clientType = isMobile ? ClientType.APP : ClientType.PC;
        if (StringUtils.isEmpty(queryData.getQueryCode())) {
            queryData.setQueryCode(getQueryCodeFromQuery(queryData.getSchemaCode(), isMobile));
        }
        BizQueryModel bizQueryModel = bizQueryFacade.getBizQuery(queryData.getSchemaCode(), queryData.getQueryCode(), clientType, null);

        //分页信息
        int page = queryData.getPage() == null ? 0 : queryData.getPage();
        int size = queryData.getSize();
        PageableImpl pageable = new PageableImpl(page * size, size);
        //生成查询条件方法
        BizObjectQueryModel bizObjectQueryModel = this.getBizObjectQuery(userId, queryData, bizQueryModel, isAuthFilter, false);
        bizObjectQueryModel.setPageable(pageable);
        bizObjectQueryModel.setSchemaCode(queryData.getSchemaCode());
        bizObjectQueryModel.setQueryCode(queryData.getQueryCode());
        bizObjectQueryModel.setOptions(queryData.getOptions());
        bizObjectQueryModel.setClientType(clientType);
        Page<BizObjectModel> data = this.queryExportDatas(bizObjectQueryModel, properties, queryData.getMobile(), columns, userId, childNumberFormat);
        long end = System.currentTimeMillis();
        log.info("查询：--{}", end - start);
        if (CollectionUtils.isNotEmpty(data.getContent())) {
            List<BizQueryColumnModel> bizQueryColumnModels = bizQueryModel.getQueryColumns();
            if (isMobile) {
                //处理移动端用户图像
                disposeUserInfo(data);
            } else {
                //处理PC端选人
                parseSpecialProperties(data, false);
            }
        }
        long masche = System.currentTimeMillis();
        log.info("处理；--{}", masche - end);
        return data;
    }

    @Override
    public FileOperationResult secondImportData(FileOperationResult operationResult) {
        if (operationResult == null) {
            throw new ServiceException(ErrCode.BIZ_QUERY_DATA_EMPTY);
        }
        if (CollectionUtils.isEmpty(operationResult.getHeadColumns()) || CollectionUtils.isEmpty(operationResult.getSecondImportData())) {
            throw new ServiceException(ErrCode.BIZ_QUERY_DATA_EMPTY);
        }
//        UserModel user = organizationFacade.getUser(operationResult.getUserId());
        List<BizQueryColumnModel> headColumns = operationResult.getHeadColumns();
        List<Map<String, Object>> secondImportData = operationResult.getSecondImportData();
        //在内存中存入子表code和properties的关系，减少查询次数--Map<String,Object>
        //在内存中存入code和headColumn的关系
        Map<String, List<BizQueryChildColumnModel>> childMap = Maps.newHashMap();
//        Map<String, BizQueryColumnModel> mainMap = Maps.newHashMap();
        for (BizQueryColumnModel columnModel : headColumns) {
            if (BizPropertyType.CHILD_TABLE == columnModel.getPropertyType()) {
                List<BizQueryChildColumnModel> childColumns = columnModel.getChildColumns();
                childMap.put(columnModel.getPropertyCode(), childColumns);
            } else {
//                mainMap.put(columnModel.getPropertyCode(), columnModel);
            }
        }
        String schemaCode = headColumns.get(0).getSchemaCode();
        BizSchemaModel bizSchemaModel = bizSchemaFacade.getBySchemaCodeWithProperty(schemaCode, true);
        List<BizPropertyModel> properties = bizSchemaModel.getProperties();
        List<BizObjectModel> bizObjectModels = Lists.newArrayListWithExpectedSize(secondImportData.size());
        Map<String, List<String>> organizationIdMap = new HashMap<>();
        organizationIdMap.put("userIdList", new ArrayList<>());
        organizationIdMap.put("errorUserIdList", new ArrayList<>());
        organizationIdMap.put("deptIdList", new ArrayList<>());
        organizationIdMap.put("errorDeptIdList", new ArrayList<>());
        for (Map<String, Object> map : secondImportData) {
            if (MapUtils.isEmpty(map)) {
                continue;
            }
            for (BizQueryColumnModel columnModel : headColumns) {
                BizPropertyModel bizProperty = properties.stream().filter(t -> t.getCode().equals(columnModel.getPropertyCode())).findAny().orElse(null);
                if (bizProperty == null) {
                    continue;
                }
                BizPropertyType propertyType = bizProperty.getPropertyType();
                if (!BizPropertyType.selectionTypes.contains(propertyType) && BizPropertyType.CHILD_TABLE != propertyType) {
                    continue;
                }
                if (BizPropertyType.selectionTypes.contains(propertyType)) {
                    boolean flag = verifySelections(map, bizProperty, organizationIdMap);
                    if (!flag) {
                        operationResult.setErrCode(ErrCode.BIZ_QUERY_DATA_VALID_FAIL);
                        return operationResult;
                    }
                    continue;
                }
                String code = bizProperty.getCode();
                if (MapUtils.isEmpty(childMap) || CollectionUtils.isEmpty(childMap.get(code))) {
                    continue;
                }
                Object childValues = map.get(code);
                if (childValues == null) {
                    continue;
                }
                List<Map<String, Object>> childDataMapList = (List<Map<String, Object>>) childValues;
                List<Map<String, Object>> childList = Lists.newArrayListWithExpectedSize(childDataMapList.size());
                List<BizQueryChildColumnModel> childColumnModels = childMap.get(code);
                for (Map<String, Object> childDataMap : childDataMapList) {
                    for (BizQueryChildColumnModel bizQueryChildColumnModel : childColumnModels) {
                        String childPropertyCode = bizQueryChildColumnModel.getPropertyCode();
                        BizSchemaModel bizSchemaBySchemaCode = bizSchemaFacade.getBySchemaCodeWithProperty(code, true);
                        List<BizPropertyModel> childPropertyList = bizSchemaBySchemaCode.getProperties();
                        BizPropertyModel propertyModel = childPropertyList.stream().filter(item -> childPropertyCode.equals(item.getCode())).findAny().orElse(null);
                        if (propertyModel == null) {
                            continue;
                        }
                        if (BizPropertyType.selectionTypes.contains(bizQueryChildColumnModel.getPropertyType())) {
                            boolean flag = this.verifySelections(childDataMap, propertyModel, organizationIdMap);
                            if (!flag) {
                                operationResult.setErrCode(ErrCode.BIZ_QUERY_DATA_VALID_FAIL);
                                return operationResult;
                            }
                        }
                    }
                    childList.add(childDataMap);
                }
                map.put(code, childList);
            }
            Map<String, Object> importData = Maps.newHashMap();
            importData.putAll(map);
            Object owner = importData.get("owner");
            if (Objects.nonNull(owner)) {
                List<SelectionValue> owner1 = (List<SelectionValue>) owner;
                SelectionValue selectionValue = owner1.get(0);
                if (selectionValue != null && StringUtils.isNotEmpty(selectionValue.getId())) {
                    String id = selectionValue.getId();
                    importData.put("owner", id);
                }
            }
            BizObjectModel bizObject = new BizObjectModel(schemaCode, importData, false);
            bizObject.setSequenceStatus(SequenceStatus.COMPLETED.toString());
            bizObjectModels.add(bizObject);
        }

        if (CollectionUtils.isNotEmpty(bizObjectModels)) {
            String queryField = operationResult.getQueryField();
            operationResult.setSuccessCount(bizObjectModels.size());
            log.info("==================批量更新========成功导入={}条,bizObjects={}", bizObjectModels.size(), JSONObject.toJSONString(bizObjectModels));
            this.addBizObjects(false, operationResult.getUserId(), bizObjectModels, queryField);
        } else {
            operationResult.setErrCode(ErrCode.BIZ_QUERY_DATA_VALID_FAIL);
        }
        return operationResult;
    }

    /**
     * 选中数据导出
     */
    private FilterExpression getCheckedFilters(List<String> objectIds) {
        FilterExpression checkedFilter = FilterExpression.empty;
        if (CollectionUtils.isEmpty(objectIds)) {
            return checkedFilter;
        }
        checkedFilter = Q.it(DefaultPropertyType.ID.getCode(), FilterExpression.Op.In, objectIds);
        return checkedFilter;
    }


    /**
     * 不能查看不是自己的草稿
     *
     * @param userId 用户id
     */
    private FilterExpression.Or filterSeqStatus(String userId) {
        FilterExpression.And eqDraft = Q.and(Q.it(DefaultPropertyType.CREATER.getCode(), FilterExpression.Op.Eq, userId),
                Q.it(DefaultPropertyType.SEQUENCE_STATUS.getCode(), FilterExpression.Op.Eq, WorkflowInstanceStatus.DRAFT.toString()));
        return Q.or(eqDraft,
                Q.it(DefaultPropertyType.SEQUENCE_STATUS.getCode(), FilterExpression.Op.NotEq, WorkflowInstanceStatus.DRAFT.toString()));
    }

    private FilterExpression getFilterList(List<FilterModel> filterList, List<BizQueryConditionModel> queryConditions, boolean customizedQuery) {
        if (CollectionUtils.isEmpty(queryConditions) && CollectionUtils.isEmpty(filterList)) {
            return FilterExpression.empty;
        }
        List<FilterExpression> filters = new ArrayList<>();
        //需要处理的可见条件
        List<BizQueryConditionModel> visibleCondition = null;
        //需要处理的隐藏条件=
        List<BizQueryConditionModel> hiddenCondition = null;
        if (CollectionUtils.isNotEmpty(queryConditions)) {
            visibleCondition = queryConditions.stream().filter(condition -> condition.getVisible()).collect(Collectors.toList());
            log.info("需要处理的可见条件:{}",visibleCondition);
            hiddenCondition = queryConditions.stream().filter(condition -> !condition.getVisible()).collect(Collectors.toList());
            log.info("需要处理的隐藏条件:{}",hiddenCondition);
        }

        if (!customizedQuery) {
            //生成可见适配条件
            if (CollectionUtils.isNotEmpty(filterList)) {
                if (CollectionUtils.isNotEmpty(visibleCondition)) {
                    createVisibleFilters(filterList, visibleCondition, filters);
                }
                if (CollectionUtils.isNotEmpty(hiddenCondition)) {
                    createHiddenFilter(filterList, hiddenCondition, filters);
                }
            }

            //可见和隐藏适配条件的编码
            List<String> codeList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(visibleCondition)) {
                List<String> propertyCodeList = visibleCondition.stream().map(BizQueryConditionModel::getPropertyCode).collect(Collectors.toList());
                codeList.addAll(propertyCodeList);
            }
            if (CollectionUtils.isNotEmpty(hiddenCondition)) {
                List<String> propertyCodeList = hiddenCondition.stream().map(BizQueryConditionModel::getPropertyCode).collect(Collectors.toList());
                codeList.addAll(propertyCodeList);
            }
            if (CollectionUtils.isEmpty(filterList)) {
                return FilterExpression.empty;
            }
            for (FilterModel filterVO : filterList) {
                List<String> propertyValue = filterVO.getPropertyValueList();
                if (filterVO.getOperatorType() != null) {
                    FilterExpression.Op op = FilterExpression.Op.Like;
                    switch (filterVO.getOperatorType()) {
                        case NEQ:
                        case IS_NOT_NULL:
                            op = FilterExpression.Op.NotEq;
                            break;
                        case GT:
                            op = FilterExpression.Op.Gt;
                            break;
                        case IT:
                            op = FilterExpression.Op.Lt;
                            break;
                        case GTEQ:
                            op = FilterExpression.Op.Gte;
                            break;
                        case ITEQ:
                            op = FilterExpression.Op.Lte;
                            break;
                        case NOT_OF:
                        case NOT_HAVE:
                        case NOT_IN:
                        case NOT_CONTAINS:
                            op = FilterExpression.Op.NotLike;
                            break;
                        case IS_NULL:
                        case EQ:
                            op = FilterExpression.Op.Eq;
                            filters.add(Q.it(filterVO.getPropertyCode(), op, filterVO.getPropertyValue()));
                            break;
                        case HAVE:
                        case IN:
                        case CONTAINS:
                        case OF:
                            op = FilterExpression.Op.Like;
                            break;
                        default:
                    }
                    if (OperatorType.IS_NULL == filterVO.getOperatorType()) {
                        filters.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                        continue;
                    }
                    if (OperatorType.IS_NOT_NULL == filterVO.getOperatorType()) {
                        filters.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNotNull, null));
                        continue;
                    }
                    if (OperatorType.IS_NULL != filterVO.getOperatorType() && OperatorType.IS_NOT_NULL != filterVO.getOperatorType()
                            && CollectionUtils.isEmpty(propertyValue)) {
                        continue;
                    }

                    // 支持 包含/不包含 多选项
                    FilterExpression containsFilter = buildContainsFilter(filterVO, op);
                    if (containsFilter != null) {
                        filters.add(containsFilter);
                        continue;
                    }

                    if (filterVO.getPropertyType() == BizPropertyType.ADDRESS) {
                        setAddressPropertyFilter(filters, filterVO, filterVO.getPropertyCode());
                    } else if (BizPropertyType.selectionTypes.contains(filterVO.getPropertyType()) || BizPropertyType.DROPDOWN_MULTI_BOX == filterVO.getPropertyType()) {
                        // 下拉多选框、选人控件，不等于使用not like
                        if (FilterExpression.Op.NotEq == op || FilterExpression.Op.NotLike == op) {
                            op = FilterExpression.Op.NotLike;
                            List<FilterExpression> filterLikes = Lists.newArrayListWithExpectedSize(filterVO.getPropertyValueList().size());
                            for (String it : filterVO.getPropertyValueList()) {
                                filterLikes.add(Q.it(filterVO.getPropertyCode(), op, it));
                            }
                            FilterExpression.Or items;
                            if (filterLikes.size() == 1) {
                                items = Q.or(filterLikes.get(0), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                            } else {
                                items = Q.or(Q.and(filterLikes), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                            }
                            filters.add(items);
                        }

                    } else if (filterVO.getPropertyType() == BizPropertyType.LOGICAL) {
                        FilterExpression.Item item = Q.it(filterVO.getPropertyCode(), op, filterVO.getPropertyValueList().get(0));
                        filters.add(item);
                    } else {

                        //列表查询 不等于 为模糊查询
                        if (FilterExpression.Op.NotEq == op) {
                            op = FilterExpression.Op.NotLike;
                        }

                        List<FilterExpression> filterExpressions = Lists.newArrayListWithExpectedSize(propertyValue.size());
                        for (String s : propertyValue) {
                            filterExpressions.add(Q.it(filterVO.getPropertyCode(), op, s));
                        }
                        // TODO 判断是否正确？
                        if (FilterExpression.Op.NotLike == op) {
                            FilterExpression.Or items;
                            if (filterExpressions.size() == 1) {
                                items = Q.or(filterExpressions.get(0), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                            } else {
                                items = Q.or(Q.and(filterExpressions), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                            }
                            filters.add(items);
                        } else {
                            filters.addAll(filterExpressions);
                        }
                    }
                    continue;
                }

                if (CollectionUtils.isEmpty(propertyValue)) {
                    continue;
                }

                if (DefaultPropertyType.SEQUENCE_STATUS.getCode().equals(filterVO.getPropertyCode())) {
                    if (CollectionUtils.isEmpty(filterVO.getPropertyValueList())) {
                        continue;
                    }
                    FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValueList());
                    filters.add(items);
                } else if (BizPropertyType.DATE == filterVO.getPropertyType() || BizPropertyType.NUMERICAL == filterVO.getPropertyType()) {

                    if (propertyValue.size() == 1) {
                        filters.add(Q.it(filterVO.getPropertyCode(), BizPropertyType.NUMERICAL == filterVO.getPropertyType() ? FilterExpression.Op.Eq : FilterExpression.Op.Like, filterVO.getPropertyValueList().get(0)));
                        continue;
                    }

                    String startValue = propertyValue.get(0);
                    String endValue = propertyValue.get(1);
                    if (BizPropertyType.DATE == filterVO.getPropertyType()) {
                        List<String> list = parseHiddrenDate(startValue, endValue);
                        if (CollectionUtils.isNotEmpty(list)) {
                            startValue = list.get(0);
                            endValue = list.get(1);
                        }
                    }
                    if (startValue != null && endValue != null) {
                        FilterExpression.And and = Q.and(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Gte, startValue), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Lte, endValue));
                        filters.add(and);
                    }
                    continue;
                }
                //查询信息是否是配置条件，如果是就无需再操作
                if (CollectionUtils.isEmpty(filterVO.getPropertyValueList()) || StringUtils.isBlank(StringUtils.strip(filterVO.getPropertyValueList().toString(), "[]"))) {
                    continue;
                }
                if (CollectionUtils.isNotEmpty(codeList)) {
                    if (codeList.contains(filterVO.getPropertyCode())) {
                        continue;
                    }
                    FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValueList());
                    filters.add(items);
                } else {
                    FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValueList());
                    filters.add(items);
                }
            }
        } else {
            if (CollectionUtils.isEmpty(filterList)) {
                return FilterExpression.empty;
            }
            for (FilterModel filterVO : filterList) {
                FilterExpression.Op op = FilterExpression.Op.Like;
                if (filterVO.getOp() != null) {
                    switch (filterVO.getOp()) {
                        case Eq:
                            op = FilterExpression.Op.Eq;
                            break;
                        case NotEq:
                            op = FilterExpression.Op.NotEq;
                            break;
                        case Like:
                            op = FilterExpression.Op.Like;
                            break;
                        case NotLike:
                            op = FilterExpression.Op.NotLike;
                            break;
                        case Gt:
                            op = FilterExpression.Op.Gt;
                            break;
                        case Lt:
                            op = FilterExpression.Op.Lt;
                            break;
                    }
                }
                if (filterVO.getPropertyType() == BizPropertyType.ADDRESS) {
                    setAddressPropertyFilter(filters, filterVO, filterVO.getPropertyCode());
                } else {
                    List<String> propertyValue = filterVO.getPropertyValueList();
                    if (CollectionUtils.isNotEmpty(propertyValue)) {
                        for (String s : propertyValue) {
                            FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, s);
                            filters.add(items);
                        }
                    } else {
                        FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, null);
                        filters.add(items);
                    }
                }
            }
        }

        if (CollectionUtils.isEmpty(filters)) {
            return FilterExpression.empty;
        }
        if (filters.size() == 1) {
            return filters.get(0);
        }
        return Q.and(filters);
    }

    private List<String> parseHiddrenDate(Object startValue, Object endValue) {
        if (null != startValue && null != endValue) {
            List<Object> list = new ArrayList<>();
            list.add(startValue);
            list.add(endValue);
            String join = Joiner.on(";").skipNulls().join(list);
            String value = PropertyValidateHelper.parseDate(join);
            List<String> strings = new ArrayList<>(Arrays.asList(value.split(";")));
            return strings;
        }
        return null;
    }

    /**
     * 包含、不包含 多条件组装
     *
     * @param filterVO 条件
     * @param op       比较条件
     * @return FilterExpression
     **/
    private FilterExpression buildContainsFilter(FilterModel filterVO, FilterExpression.Op op) {
        if (OperatorType.CONTAINS != filterVO.getOperatorType() && OperatorType.NOT_CONTAINS != filterVO.getOperatorType()) {
            return null;
        }
        // 文本类型
        if (Arrays.asList(BizPropertyType.SHORT_TEXT, BizPropertyType.RADIO, BizPropertyType.CHECKBOX,
                BizPropertyType.DROPDOWN_BOX, BizPropertyType.DROPDOWN_MULTI_BOX).contains(filterVO.getPropertyType())) {

            List<FilterExpression> containsFilters = filterVO.getPropertyValueList().stream().filter(StringUtils::isNotEmpty).distinct()
                    .map(it -> Q.it(filterVO.getPropertyCode(), op, it)).collect(Collectors.toList());

            if (CollectionUtils.isEmpty(containsFilters)) {
                return null;
            }
            if (containsFilters.size() == 1) {
                if (OperatorType.CONTAINS == filterVO.getOperatorType()) {
                    return containsFilters.get(0);
                } else {
                    return Q.or(containsFilters.get(0), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                }
            } else {
                if (OperatorType.CONTAINS == filterVO.getOperatorType()) {
                    return Q.or(containsFilters);
                } else {
                    return Q.or(Q.and(containsFilters), Q.it(filterVO.getPropertyCode(), FilterExpression.Op.IsNull, null));
                }
            }
        }
        return null;
    }

    /**
     * 设置地址控件属性过滤值
     */
    private void setAddressPropertyFilter(List<FilterExpression> filters, FilterModel filterVO, String propertyCode) {

        if (filterVO.getPropertyType() == BizPropertyType.ADDRESS) {
            log.info("第6097行，为地址控件",filterVO.getPropertyType());
            String address = filterVO.getPropertyValueList().get(0);
            Map<String, String> addressMap = JSON.parseObject(address, new TypeReference<Map<String, String>>() {
            });
            String provinceAdcode = addressMap.get("provinceAdcode");
            String cityAdcode = addressMap.get("cityAdcode");
            String districtAdcode = addressMap.get("districtName");
            FilterExpression.Op op;
            boolean isNotEq = (filterVO.getOperatorType() != null && (OperatorType.NEQ == filterVO.getOperatorType() || OperatorType.NOT_CONTAINS == filterVO.getOperatorType()));
            if (isNotEq) {
                op = FilterExpression.Op.NotLike;
            } else {
                op = FilterExpression.Op.Like;
            }
            List filterTemplates = new ArrayList<FilterExpression>();
            if (StringUtils.isNotEmpty(provinceAdcode)) {
                filterTemplates.add(Q.it(propertyCode, op, provinceAdcode));
            }
            if (StringUtils.isNotEmpty(cityAdcode)) {
                filterTemplates.add(Q.it(propertyCode, op, cityAdcode));
            }
            if (StringUtils.isNotEmpty(districtAdcode)) {
                filterTemplates.add(Q.it(propertyCode, op, districtAdcode));
            }
            if (isNotEq) {
                filters.add(Q.or(Q.and(filterTemplates), Q.it(propertyCode, FilterExpression.Op.IsNull, null)));
            } else {
                filters.add(Q.and(filterTemplates));
            }
        } else {
            log.info("=======================执行到这里了===============，{}", filterVO.getPropertyValueList().get(0));
            if (StringUtils.isNotBlank(filterVO.getPropertyValueList().get(0))) {
                BizPropertyType propertyType11 = filterVO.getPropertyType();
                log.info("propertyType11:{}",propertyType11);
                if (BizPropertyType.SHORT_TEXT.equals(propertyType11)){
                    //获取接口标识信息,只对list_reverse_sheet生效
                    String propertyValue = filterVO.getPropertyValue();
                    String[] split = propertyValue.split(";");
                    String index = split[split.length-1];
                    if ("list_reverse_sheet".equals(index)){
                        filters.add(Q.it(propertyCode, FilterExpression.Op.Eq, filterVO.getPropertyValueList().get(0)));
                        log.info("来自接口{}，propertyCode1为{}的短文本，执行了精准查询",index,propertyType11);
                    }else {
                        filters.add(Q.it(propertyCode, FilterExpression.Op.Like, filterVO.getPropertyValueList().get(0)));
                        log.info("propertyCode1为{}，但不是指定接口，执行了模糊查询",propertyType11);
                    }
                }else {
                    filters.add(Q.it(propertyCode, FilterExpression.Op.Like, filterVO.getPropertyValueList().get(0)));
                    log.info("propertyCode1为{}，执行了模糊查询",propertyType11);
                }
            }
        }
    }



    /**
     * 生成隐藏过滤条件
     *
     * @param hiddenCondition 查询条件
     * @param filters         过滤
     */
    private void createHiddenFilter(List<FilterModel> filterVOs, List<BizQueryConditionModel> hiddenCondition, List<FilterExpression> filters) {
        //如果表单配置的过滤条件无在这里过滤
        filterVOs = filterVOs.stream().filter(filterVO -> Objects.isNull(filterVO.getOperatorType())).collect(Collectors.toList());
        for (BizQueryConditionModel condition : hiddenCondition) {
            //oracle数据库下 默认值为null，生成过滤条件异常。
            String defaultValue = StringUtils.isBlank(condition.getDefaultValue()) ? "" : condition.getDefaultValue();
            List<String> properValue = Arrays.asList(defaultValue.split(";"));
            FilterExpression.Item item = null;
            if (BizPropertyType.selectionTypes.contains(condition.getPropertyType())) {
                filterVOs = filterVOs.stream().filter(t -> BizPropertyType.selectionTypes.contains(t.getPropertyType())).collect(Collectors.toList());

                List<String> idsP = new ArrayList<>();
                List<String> idsDpt = new ArrayList<>();
                List<String> idsSelection = new ArrayList<>();
                filterVOs.forEach(t -> {
                    List<String> values = t.getPropertyValueList();
                    if (CollectionUtils.isEmpty(values)) {
                        return;
                    }
                    if (Objects.equals(t.getPropertyCode(), DefaultPropertyType.CREATER.getCode()) || Objects.equals(t.getPropertyCode(), DefaultPropertyType.OWNER.getCode())) {
                        idsP.addAll(values);
                    } else if (Objects.equals(t.getPropertyCode(), DefaultPropertyType.CREATED_DEPT_ID.getCode()) || Objects.equals(t.getPropertyCode(), DefaultPropertyType.OWNER_DEPT_ID.getCode())) {
                        idsDpt.addAll(values);
                    }
                    if (CollectionUtils.isNotEmpty(values)) {
                        idsSelection.addAll(values);
                    }
                });
                List<String> defaults = filterVOs.get(0).getDefaultProperties();
                if (Objects.equals(condition.getDefaultValue(), "1")) {
                    //本人
                    if (defaults.contains(condition.getPropertyCode())) {
                        item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, idsP);
                        if (CollectionUtils.isNotEmpty(idsP)) {
                            filters.add(item);
                        }
                    } else {
                        if (CollectionUtils.isNotEmpty(idsSelection)) {
                            List<FilterExpression> items = Lists.newArrayListWithExpectedSize(idsSelection.size());
                            for (String id : idsSelection) {
                                items.add(Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, id));
                            }
                            if (items.size() == 1) {
                                filters.add(items.get(0));
                            } else {
                                filters.add(Q.or(items));
                            }
                        }
                    }
                } else if (Objects.equals(condition.getDefaultValue(), "2")) {
                    //本部门
                    if (defaults.contains(condition.getPropertyCode())) {
                        item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, idsDpt);
                        if (CollectionUtils.isNotEmpty(idsDpt)) {
                            filters.add(item);
                        }
                    } else {
                        List<FilterExpression> items = Lists.newArrayListWithExpectedSize(idsSelection.size());
                        for (String id : idsSelection) {
                            FilterExpression.Item it = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, id);
                            items.add(it);
                        }
                        //对条件判空
                        if (CollectionUtils.isNotEmpty(items)) {
                            if (items.size() == 1) {
                                filters.add(items.get(0));
                            } else {
                                filters.add(Q.or(items));
                            }
                        }
                    }
                }
                continue;
            }

            if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.CHECKBOX) {
                item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, properValue);
                if (CollectionUtils.isNotEmpty(properValue)) {
                    filters.add(item);
                }
                continue;
            }
            if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.SELECT) {
                //多选精确查询

                if (CollectionUtils.isNotEmpty(properValue) && properValue.size() > 1) {
                    String regex = generateRegex(properValue);
                    FilterExpression.Item it = Q.it(condition.getPropertyCode(), FilterExpression.Op.Reg, regex);
                    filters.add(it);
                    continue;
                } else if (CollectionUtils.isEmpty(properValue)) {
                    continue;
                } else if (CollectionUtils.isNotEmpty(properValue) && properValue.size() == 1) {
                    String s = properValue.get(0);
                    if (StringUtils.isEmpty(s)) {
                        continue;
                    }
                    item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, properValue);
                    filters.add(item);
                    continue;
                }
            }
            if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.RANGE || condition.getPropertyType() == BizPropertyType.NUMERICAL || condition.getPropertyType() == BizPropertyType.DATE) {
                //拿到传入的条件
                FilterModel filter = null;
                if (CollectionUtils.isNotEmpty(filterVOs)) {
                    List<FilterModel> collect = filterVOs.stream().filter(filterVO -> Objects.equals(filterVO.getPropertyCode(), condition.getPropertyCode())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect)) {
                        filter = collect.get(0);
                    }
                }
                createScopeFilter(condition, filter, filters, Boolean.TRUE);
                continue;
            }
            if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.INPUT) {
                if (condition.getPropertyType() == BizPropertyType.ADDRESS) {
                    List<FilterModel> collect = filterVOs.stream().filter(f -> condition.getPropertyCode().equals(f.getPropertyCode())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect) && CollectionUtils.isNotEmpty(collect.get(0).getPropertyValueList())) {
                        String address = collect.get(0).getPropertyValueList().get(0);
                        Map<String, String> addressMap = JSON.parseObject(address, new TypeReference<Map<String, String>>() {
                        });
                        String provinceAdcode = addressMap.get("provinceAdcode");
                        String cityAdcode = addressMap.get("cityAdcode");
                        String districtAdcode = addressMap.get("districtName");
                        if (StringUtils.isNotEmpty(provinceAdcode)) {
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, provinceAdcode);
                            filters.add(item);
                        }
                        if (StringUtils.isNotEmpty(cityAdcode)) {
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, cityAdcode);
                            filters.add(item);
                        }
                        if (StringUtils.isNotEmpty(districtAdcode)) {
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, districtAdcode);
                            filters.add(item);
                        }
                    }
                } else if (condition.getPropertyType() == BizPropertyType.LOGICAL) {
                    List<FilterModel> collect = filterVOs.stream().filter(f -> condition.getPropertyCode().equals(f.getPropertyCode())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect) && CollectionUtils.isNotEmpty(collect.get(0).getPropertyValueList())) {
                        String logic = collect.get(0).getPropertyValueList().get(0);
                        if (StringUtils.isNotEmpty(logic)) {
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, logic);
                            filters.add(item);
                        }
                    }
                } else {
                    List<FilterModel> collect = filterVOs.stream().filter(filterVO -> Objects.equals(filterVO.getPropertyCode().toString(), condition.getPropertyCode().toString())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect)) {
                        List<String> propertyValue = collect.get(0).getPropertyValueList();
                        if (CollectionUtils.isNotEmpty(propertyValue)) {
                            String s = collect.get(0).getPropertyValueList().get(0);
                            if (StringUtils.isNotEmpty(s)) {
                                item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, s);
                                filters.add(item);
                            }
                        }
                    }

                }
                continue;
            }
            List<FilterModel> collect = filterVOs.stream().filter(filterVO -> Objects.equals(filterVO.getPropertyCode(), condition.getPropertyCode())).collect(Collectors.toList());
            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, collect.get(0).getPropertyValueList().get(0));
            filters.add(item);
            continue;
        }

    }

    /**
     * 获取范围查询条件
     *
     * @param condition 查询条件
     * @param filterVO  查询条件
     * @param filters   过滤
     * @param isDefault 是否默认
     */
    private void createScopeFilter(BizQueryConditionModel condition, FilterModel filterVO, List<FilterExpression> filters, Boolean isDefault) {
        //默认值情况
        FilterExpression.Item itemStart = null;
        FilterExpression.Item itemEnd = null;
        List<String> values = filterVO == null ? null : filterVO.getPropertyValueList();
        Object startValue = null;
        Object endValue = null;
        if (CollectionUtils.isEmpty(values)) {
            startValue = isDefault ? (condition.getStartValue() == null ? null : ("".equals(condition.getStartValue()) ? null : condition.getStartValue())) : (values == null ? null : values.get(0));
            endValue = isDefault ? (condition.getEndValue() == null ? null : ("".equals(condition.getEndValue()) ? null : condition.getEndValue())) : (values == null ? null : values.get(1));
        } else if (values.size() == 1) {
            startValue = isDefault ? (condition.getStartValue() == null ? null : ("".equals(condition.getStartValue()) ? null : condition.getStartValue())) : values.get(0);
            endValue = isDefault ? (condition.getEndValue() == null ? null : ("".equals(condition.getEndValue()) ? null : condition.getEndValue())) : values.get(0);
        } else if (values.size() == 2) {
            if (isDefault && (!condition.getDateType().equals(0))) {
                startValue = values.get(0);
                endValue = values.get(1);
            } else if (!isDefault) {
                startValue = values.get(0);
                endValue = values.get(1);
            } else if (isDefault && condition.getDateType().equals(0)) {
                startValue = condition.getStartValue() == null ? null : ("".equals(condition.getStartValue()) ? null : condition.getStartValue());
                endValue = condition.getEndValue() == null ? null : ("".equals(condition.getEndValue()) ? null : condition.getEndValue());
            }
        }

        if (isDefault && condition.getPropertyType() == BizPropertyType.DATE) {
            List<String> list = parseHiddrenDate(startValue, endValue);
            if (CollectionUtils.isNotEmpty(list)) {
                startValue = list.get(0);
                endValue = list.get(1);
            }
        }
        if (null != startValue) {
            itemStart = Q.it(condition.getPropertyCode(), FilterExpression.Op.Gte, startValue);
        }
        if (null != endValue) {
            itemEnd = Q.it(condition.getPropertyCode(), FilterExpression.Op.Lte, endValue);
        }
        if (itemStart != null && itemEnd != null) {
            FilterExpression.And and = Q.and(itemStart, itemEnd);
            filters.add(and);
            return;
        }
        if (itemStart == null && itemEnd == null) {
            return;
        }
        filters.add(itemStart == null ? itemEnd : itemStart);
    }

    private void createVisibleFilters(List<FilterModel> filterVOs, List<BizQueryConditionModel> visibleCondition, List<FilterExpression> filters) {
        //如果表单配置的过滤条件无在这里过滤
        filterVOs = filterVOs.stream().filter(filterVO -> Objects.isNull(filterVO.getOperatorType())).collect(Collectors.toList());
        log.info("------3------条件中过滤operatorType为null的:{}",filterVOs);
        for (FilterModel filterVO : filterVOs) {
            boolean machAble = false;   //de

            if (BizPropertyType.WORK_SHEET == filterVO.getPropertyType()) {
                if (CollectionUtils.isEmpty(filterVO.getPropertyValueList())) {
                    continue;
                }
                FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValueList().get(0));
                filters.add(items);
                continue;
            }
            if (CollectionUtils.isNotEmpty(visibleCondition)) {
                for (BizQueryConditionModel condition : visibleCondition) {
                    FilterExpression.Item item = null;
                    if (filterVO.getPropertyCode().equals(condition.getPropertyCode())) {
                        machAble = true;
                        if (CollectionUtils.isEmpty(filterVO.getPropertyValueList())) {
                            continue;
                        }
                        if (BizPropertyType.selectionTypes.contains(condition.getPropertyType())) {
                            List<String> defaults = filterVO.getDefaultProperties();
                            if (defaults.contains(filterVO.getPropertyCode()) &&
                                    (DefaultPropertyType.OWNER_DEPT_ID.getCode().equals(filterVO.getPropertyCode()) ||
                                            DefaultPropertyType.CREATED_DEPT_ID.getCode().equals(filterVO.getPropertyCode()))) {
                                //创建人部门过滤权限
                                List<String> departmentIds = Lists.newArrayList();
                                for (String deptId : filterVO.getPropertyValueList()) {
                                    List<String> deptIds = Lists.newArrayList();
                                    departmentIds.add(deptId);

                                    List<DepartmentModel> departmentModels = organizationFacade.getDepartmentsChildList(departmentIds, true);
                                    if (CollectionUtils.isNotEmpty(departmentModels)) {
                                        departmentModels.stream().forEach(departmentModel -> {
                                            deptIds.add(departmentModel.getId());
                                        });
                                        deptIds.add(deptId);
                                        departmentIds.addAll(deptIds);
                                    } else {
                                        departmentIds.add(deptId);
                                    }
                                }
                                item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, departmentIds);
                                if (CollectionUtils.isNotEmpty(departmentIds)) {
                                    filters.add(item);
                                }
                                break;
                            }

                            if (defaults.contains(filterVO.getPropertyCode())) {
                                item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValueList());
                                if (CollectionUtils.isNotEmpty(filterVO.getPropertyValueList())) {
                                    filters.add(item);
                                }
                                break;
                            }
                            List<FilterExpression> filterTemplates = Lists.newArrayListWithExpectedSize(filterVO.getPropertyValueList().size());
                            for (String s : filterVO.getPropertyValueList()) {
                                filterTemplates.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, s));
                            }
                            if (CollectionUtils.isNotEmpty(filterTemplates)) {
                                if (filterTemplates.size() == 1) {
                                    filters.add(filterTemplates.get(0));
                                } else {
                                    filters.add(Q.or(filterTemplates));
                                }
                            }
                            break;
                        }
                        if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.CHECKBOX) {
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValueList());
                            filters.add(item);
                            break;
                        }
                        if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.SELECT) {
                            //修改  多选精确查询
                            List<String> propertyValue = filterVO.getPropertyValueList();
                            if (CollectionUtils.isNotEmpty(propertyValue) && propertyValue.size() > 1) {
                                String regex = generateRegex(propertyValue);
                                FilterExpression.Item it = Q.it(condition.getPropertyCode(), FilterExpression.Op.Reg, regex);
                                filters.add(it);
                                break;
                            }
                            //修改 修改  多选精确查询
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValueList());
                            filters.add(item);
                            break;
                        }
                        if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.RANGE || condition.getPropertyType() == BizPropertyType.NUMERICAL || condition.getPropertyType() == BizPropertyType.DATE) {
                            createScopeFilter(condition, filterVO, filters, false);
                            break;
                        }
                        if (condition.getPropertyType() == BizPropertyType.LOGICAL) {
                            item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValueList().get(0));
                            filters.add(item);
                            break;
                        }
                        if (condition.getPropertyType() == BizPropertyType.DROPDOWN_MULTI_BOX) {

                            if (filterVO.getPropertyValueList().size() > 1) {
                                List<FilterExpression> filterTemplates = new ArrayList<>();
                                filterVO.getPropertyValueList().forEach(it -> {
                                    filterTemplates.add(Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, it));
                                });
                                filters.add(Q.or(filterTemplates));
                            } else {
                                filters.add(Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValueList().get(0)));
                            }
                            break;
                        }
                        if (condition.getDisplayType() != null && condition.getDisplayType() == DisplayType.INPUT) {
                            /*
                             * 地址控件类型查询条件，根据编码查询
                             * 格式:
                             *    省
                             *    省-市
                             *    省-市-区
                             */
                            setAddressPropertyFilter(filters, filterVO, condition.getPropertyCode());
                            break;
                        }
                        item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValueList().get(0));
                        filters.add(item);
                        break;
                    }
                }
            }
        }
    }

    /**
     * 根据选项构建正则表达式查询条件
     */
    private String generateRegex(List<String> propertyValue) {
        StringBuilder sb = new StringBuilder(propertyValue.get(0));
        for (int i = 1; i < propertyValue.size(); i++) {
            sb.append('|').append(propertyValue.get(i));
        }
        return sb.toString();
    }

    /**
     * 设置用户显示图像
     *
     * @param data 分页数据
     */
    private void disposeUserInfo(Page<BizObjectModel> data) {
        if (CollectionUtils.isEmpty(data.getContent())) {
            return;
        }
        for (BizObjectModel bizObject : data.getContent()) {
            List<SelectionValue> selectionValues = (List<SelectionValue>) bizObject.get(DefaultPropertyType.CREATER.getCode());
            if (CollectionUtils.isNotEmpty(selectionValues)) {
                bizObject.put("imgUrl", selectionValues.get(0).getImgUrl());
                bizObject.put("originator", selectionValues.get(0).getName());
            }
        }
    }

    /**
     * 处理PC端选人控件展示
     *
     * @param data 分页数据
     */
    private void parseSpecialProperties(Page<BizObjectModel> data, Boolean isExport) {
        //获选人数据项
        BizObjectModel objectModel = data.getContent().get(0);
        BizSchemaModel bizSchema = bizSchemaFacade.getBySchemaCodeWithProperty(objectModel.getSchemaCode(), null);
        if (isExport) {
            List<String> selectCodes = getPropertyCodeList(objectModel, BizPropertyType.selectionTypes);
            if (CollectionUtils.isEmpty(selectCodes)) {
                return;
            }
            if (log.isDebugEnabled()) {
                log.debug("需要处理的选人数据项为{}", JSON.toJSONString(selectCodes));
            }
            Set<String> dataCodes = null;
            for (String selectCode : selectCodes) {
                for (BizObjectModel bizObject : data.getContent()) {
                    if (CollectionUtils.isEmpty(dataCodes)) {
                        dataCodes = bizObject.getData().keySet();
                        if (log.isDebugEnabled()) {
                            log.debug("需要展示的数据项为{}", JSON.toJSONString(dataCodes));
                        }
                    }
                    if (!dataCodes.contains(selectCode)) {
                        if (log.isDebugEnabled()) {
                            log.debug("不需要展示的选人数据项为{}", selectCode);
                        }
                        break;
                    }
                    if (bizObject.get(selectCode) == null) {
                        continue;
                    }
                    List<SelectionValue> selectionValues = (List<SelectionValue>) bizObject.get(selectCode);
                    bizObject.put(selectCode, getUserNames(selectionValues));
                }
            }
            //处理单据状态
            if (data.getContent().get(0).getData().containsKey(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
                for (BizObjectModel bizObjectModel : data.getContent()) {
                    bizObjectModel.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), parseSequenceStatus(bizObjectModel));
                }
            }
            //获取逻辑型
            List<BizPropertyModel> logicalModels = bizSchema.getProperties().stream().filter(t -> t.getPropertyType() == BizPropertyType.LOGICAL).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(logicalModels)) {
                List<String> logicals = logicalModels.stream().map(BizPropertyModel::getCode).collect(Collectors.toList());
                Set<String> logicalDataCodes = null;
                for (String logical : logicals) {
                    for (BizObjectModel bizObjectModel : data.getContent()) {
                        if (CollectionUtils.isEmpty(logicalDataCodes)) {
                            logicalDataCodes = bizObjectModel.getData().keySet();
                        }
                        if (!logicalDataCodes.contains(logical)) {
                            break;
                        }
                        if (bizObjectModel.get(logical) == null) {
                            continue;
                        }
                        bizObjectModel.put(logical, disposeLogic(bizObjectModel.getString(logical)));
                    }

                }
            }
        }

    }

    /**
     * 从列表数据中获取到用户名
     *
     * @return Object
     */
    public Object getUserNames(List<SelectionValue> selectionValues) {
        if (selectionValues == null) {
            return "";
        }
        return selectionValues.stream().map(SelectionValue::getName).collect(Collectors.joining(", "));
    }

    /**
     * 处理审批意见
     */
    public Object disposeLogic(String logic) {
        switch (logic) {
            case "1":
                return "是";
            case "0":
                return "否";
            case "true":
                return "是";
            case "false":
                return "否";
            default:
                return "";
        }
    }

    private List<String> getRelevanceFormConfigColumn(String schemaCode, String sheetCode, String relevanceFormCode) {
        //当前表单
        BizFormModel bizFormModel = bizFormFacade.getBySchemaCodeAndFormCode(schemaCode, sheetCode);
        List<String> showField = BizFormUtil.getRelevanceFormShowField(bizFormModel, relevanceFormCode);
        String regex = ".";
        String transferRegex = "\\.";
        List<String> configColumnList = Collections.emptyList();
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(showField)) {
            List<String> cg = new ArrayList<>();
            List<String> c1 = showField.stream().filter(t -> !t.contains(regex)).collect(Collectors.toList());
            List<String> c2 = showField.stream().filter(t -> t.contains(regex)).collect(Collectors.toList());
            List<String> c3 = c2.stream().map(s -> s.split(transferRegex)[0]).distinct().collect(Collectors.toList());
            cg.addAll(c1);
            cg.addAll(c3);
            configColumnList = cg;
        }
        return configColumnList;
    }

    private void parseAddressAndReference(Page<BizObjectModel> data, List<BizQueryColumnModel> columnModels, Boolean isExport, String queryCode) {
        if (CollectionUtils.isEmpty(columnModels) || CollectionUtils.isEmpty(data.getContent())) {
            return;
        }
        if (isExport) {
            //获取模板信息
            List<BizQueryColumnModel> collect = columnModels.stream().filter(t -> t.getPropertyType() == BizPropertyType.NUMERICAL).collect(Collectors.toList());
            Map<String, String> mapTemp = new HashMap<>();
            if (CollectionUtils.isNotEmpty(collect)) {
                BizQueryModel bizQuery = bizQueryFacade.getBizQuery(columnModels.get(0).getSchemaCode(), queryCode, ClientType.PC, null);
                String formCode = null;
                if (bizQuery != null && org.apache.commons.collections4.CollectionUtils.isNotEmpty(bizQuery.getQueryActions())) {
                    BizQueryActionModel bizQueryAction = bizQuery.getQueryActions().stream().filter(t -> t.getQueryActionRelativeType() != null && t.getQueryActionRelativeType() == QueryActionRelativeType.BIZSHEET && StringUtils.isNotEmpty(t.getRelativeCode())).findAny().orElse(null);
                    if (bizQueryAction != null) {
                        formCode = bizQueryAction.getRelativeCode();
                        log.debug("获取到的表单编码为{}", formCode);
                    }
                }
                if (StringUtils.isEmpty(formCode)) {
                    formCode = bizFormFacade.getFormCodeBySchemaCode(columnModels.get(0).getSchemaCode());
                }
                BizForm sheetModel = bizFormService.getBySchemaCodeAndFormCode(columnModels.get(0).getSchemaCode(), formCode);
                Map map = JSON.parseObject(sheetModel.getPublishedAttributesJson(), Map.class);
                for (BizQueryColumnModel bizQueryColumnModel : collect) {
                    if (map.containsKey(bizQueryColumnModel.getPropertyCode())) {
                        Map map1 = JSON.parseObject(map.get(bizQueryColumnModel.getPropertyCode()).toString(), Map.class);
                        Map map2 = JSON.parseObject(map1.get("options").toString(), Map.class);
                        mapTemp.put(bizQueryColumnModel.getPropertyCode(), map2.get("format").toString());
                    }
                }
                log.debug("获取到的表单编码为{}", formCode);

            }
            columnModels = columnModels.stream().filter(t -> t.getPropertyType() == BizPropertyType.ADDRESS || t.getPropertyType() == BizPropertyType.WORK_SHEET || t.getPropertyType() == BizPropertyType.NUMERICAL).collect(Collectors.toList());
            for (BizQueryColumnModel columnModel : columnModels) {
                for (BizObjectModel bizObjectModel : data.getContent()) {
                    if (columnModel.getPropertyType() == BizPropertyType.ADDRESS) {
                        String json = null;
                        if (bizObjectModel.get(columnModel.getPropertyCode()) != null) {
                            json = bizObjectModel.get(columnModel.getPropertyCode()).toString();
                        }
                        if ("{}".equals(json)) {
                            json = null;
                            bizObjectModel.put(columnModel.getPropertyCode(), null);
                            log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>NO.23>>>> json为null");
                        }
                        if (StringUtils.isNotEmpty(json)) {
                            Map map = JSONObject.parseObject(json, Map.class);
                            String name = "";
                            if (map.get("provinceName") != null) {
                                name = name + map.get("provinceName");
                            }
                            if (map.get("cityName") != null) {
                                name = name + map.get("cityName");
                            }
                            if (map.get("districtName") != null) {
                                name = name + map.get("districtName");
                            }
                            if (map.get("address") != null) {
                                name = name + map.get("address");
                            }
                            log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>NO.33>>>> {}", name);
                            bizObjectModel.put(columnModel.getPropertyCode(), name);
                        }
                    }
                    if (columnModel.getPropertyType() == BizPropertyType.WORK_SHEET) {
                        if (bizObjectModel.get(columnModel.getPropertyCode()) != null) {
                            Object o = bizObjectModel.get(columnModel.getPropertyCode());
                            //修改:
                            bizObjectModel.put(columnModel.getPropertyCode(), o == "null" ? null : o);
                            log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>NO.43>>>> {}", o);
                        }
                    }
                    if (columnModel.getPropertyType() == BizPropertyType.NUMERICAL) {
                        if (bizObjectModel.get(columnModel.getPropertyCode()) == null) {
                            continue;
                        }
                        DecimalFormat df = null;
                        switch (mapTemp.get(columnModel.getPropertyCode())) {

                            case "integer":
                                df = new DecimalFormat("#");
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.get(columnModel.getPropertyCode())));
                                break;
                            case "tenths":
                                df = new DecimalFormat("###,###.#");
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.get(columnModel.getPropertyCode())));
                                break;
                            case "percentile":
                                df = new DecimalFormat("###,###.##");
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.get(columnModel.getPropertyCode())));
                                break;
                            case "ratio":
                                df = new DecimalFormat("#%");
                                BigDecimal ratioResult = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioResult.longValue() / 100.0));
                                break;
                            case "ratio.tenths":
                                df = new DecimalFormat("##.#" + "%");
                                BigDecimal ratioTenths = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioTenths.longValue() / 100.0));
                                break;
                            case "ratio.percentile":
                                df = new DecimalFormat("##.##" + "%");
                                BigDecimal ratioPercentile = (BigDecimal) bizObjectModel.get(columnModel.getPropertyCode());
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(ratioPercentile.longValue() / 100.0));
                                break;
                            case "HK.percentile":
                                df = new DecimalFormat("HK$#,###.00");
                                bizObjectModel.put(columnModel.getPropertyCode(), df.format(bizObjectModel.get(columnModel.getPropertyCode())));
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
    }

    /**
     * api : 将引用数据项放入查询模型
     * <p>
     * bizObjectQueryModel 中 的Map<String, Object> quotes  里面有三层结构  第一层  key为 模型编码（可以为子表） value为对应该模型编码下的引用的数据项  第二层 key 为关联表单编码 value为该关联表单下的引用数据项 第三层  key为引用的数据项编码 value 为该数据项的几层引用
     *
     * @param bizObjectQueryModel 查询条件
     * @param schemaCode          模型编码
     * @return 查询条件
     */
    private BizObjectQueryModel parseQueries(BizObjectQueryModel bizObjectQueryModel, String schemaCode) {
        Map<String, Map<String, List<QuoteModel>>> quoteModels = parseQuote(schemaCode);
        BizSchemaModel bizSchema = bizSchemaFacade.getBySchemaCodeWithProperty(schemaCode, true);
        List<BizPropertyModel> properties = bizSchema.getProperties();
        List<String> subSchemaCodes = properties.stream().filter(propertyModel -> propertyModel.getPropertyType() == BizPropertyType.CHILD_TABLE).map(BizPropertyModel::getCode).collect(Collectors.toList());
        Map<String, Map<String, Map<String, List<QuoteModel>>>> object = Maps.newHashMapWithExpectedSize(subSchemaCodes.size() + 1);
        object.put(schemaCode, quoteModels);
        if (CollectionUtils.isEmpty(subSchemaCodes)) {
            Map<String, Object> result = new HashMap<>(object);
            bizObjectQueryModel.setQuotes(result);
            return bizObjectQueryModel;
        }
        for (String sub : subSchemaCodes) {
            Map<String, Map<String, List<QuoteModel>>> quotes = parseQuote(sub);
            object.put(sub, quotes);
        }
        Map<String, Object> result = new HashMap<>(object);
        bizObjectQueryModel.setQuotes(result);
        return bizObjectQueryModel;
    }

    private Map<String, Map<String, List<QuoteModel>>> parseQuote(String schemaCode) {
        BizSchemaModel bizSchema = bizSchemaFacade.getBySchemaCodeWithProperty(schemaCode, true);
        List<BizPropertyModel> properties = bizSchema.getProperties();
        if (CollectionUtils.isEmpty(properties)) {
            throw new ServiceException(ErrCode.BIZ_PROPERTY_NOT_EXIST.getErrCode(), ErrCode.BIZ_PROPERTY_NOT_EXIST.getErrMsg(), "数据项为空");
        }
        List<BizPropertyModel> workSheets = properties.stream().filter(propertyModel -> propertyModel.getPropertyType() == BizPropertyType.WORK_SHEET).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workSheets)) {
            return Maps.newHashMap();
        }
        Map<String, Map<String, List<QuoteModel>>> quotes = Maps.newHashMapWithExpectedSize(workSheets.size());
        for (BizPropertyModel bizPropertyModel : workSheets) {
            List<QuoteModel> quoteCodes = bizPropertyModel.getQuoteCodes();
            if (CollectionUtils.isEmpty(quoteCodes)) {
                continue;
            }
            String code = bizPropertyModel.getCode();
            Map<String, List<QuoteModel>> map = Maps.newHashMapWithExpectedSize(quoteCodes.size());
            for (QuoteModel quoteModel : quoteCodes) {
                List<QuoteModel> list = new ArrayList<>();
                quoteModel.setRelativePropertyCode(bizPropertyModel.getCode());
                list.add(quoteModel);
                parseQuoteModel(quoteModel, list);
                map.put(quoteModel.getCode(), list);
            }
            quotes.put(code, map);
        }
        return quotes;
    }

    /**
     * api : 计算每一个引用数据项所有的引用   并保持引用全过程
     *
     * @param quoteModel 引用数据项信息
     * @param result     引用信息
     * @return 引用信息
     */
    private List<QuoteModel> parseQuoteModel(QuoteModel quoteModel, List<QuoteModel> result) {
        String relativeCode = quoteModel.getRelativeCode();
        String relativeSchemaCode = quoteModel.getRelativeSchemaCode();
        BizSchemaModel bizSchema = bizSchemaFacade.getBySchemaCodeWithProperty(relativeSchemaCode, true);
        List<BizPropertyModel> properties = bizSchema.getProperties();
        if (CollectionUtils.isEmpty(properties)) {
            throw new ServiceException(ErrCode.BIZ_PROPERTY_NOT_EXIST.getErrCode(), ErrCode.BIZ_PROPERTY_NOT_EXIST.getErrMsg(), "数据项为空");
        }
        List<BizPropertyModel> workSheets = properties.stream().filter(propertyModel -> propertyModel.getPropertyType() == BizPropertyType.WORK_SHEET).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workSheets)) {
            if (CollectionUtils.isNotEmpty(result)) {
                List<QuoteModel> collect = result.stream().filter(quote -> quote.getCode().equals(quoteModel.getCode())).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(collect)) {
                    result.add(quoteModel);
                    return result;
                }
                return result;
            }
            result.add(quoteModel);
            return result;
        }
        List<QuoteModel> quoteModels = Lists.newArrayListWithExpectedSize(workSheets.size());
        for (BizPropertyModel bizPropertyModel : workSheets) {
            List<QuoteModel> quoteCodes = bizPropertyModel.getQuoteCodes();
            if (CollectionUtils.isEmpty(quoteCodes)) {
                continue;
            }
            List<QuoteModel> quotes = quoteCodes.stream().filter(quote -> Objects.equals(quote.getCode(), relativeCode)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(quotes)) {
                continue;
            }
            quotes.get(0).setRelativePropertyCode(bizPropertyModel.getCode());
            quoteModels.add(quotes.get(0));
        }
        if (CollectionUtils.isEmpty(quoteModels)) {
            if (CollectionUtils.isNotEmpty(result)) {
                List<QuoteModel> collect = result.stream().filter(quote -> quote.getCode().equals(quoteModel.getCode())).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(collect)) {
                    result.add(quoteModel);
                    return result;
                }
                return result;
            }
        }
        result.add(quoteModels.get(0));
        parseQuoteModel(quoteModels.get(0), result);
        return result;

    }

    private boolean verifySelections(Map<String, Object> dataMap, BizPropertyModel bizPropertyModel, Map<String, List<String>> organizationIdMap) {
        if (MapUtils.isEmpty(dataMap)) {
            return false;
        }
        String propertyCode = bizPropertyModel.getCode();
        Object value = dataMap.get(propertyCode);
        if (value == null || StringUtils.isBlank(value.toString())) {
            return !bizPropertyModel.getPropertyEmpty();
        }
        List<Map<String, Object>> selectDataMapList = (List<Map<String, Object>>) value;
        BizPropertyType propertyType = bizPropertyModel.getPropertyType();
        switch (propertyType) {
            case STAFF_SELECTOR:
                if (selectDataMapList.size() > 1) {
                    return false;
                }
                if (!checkUser(selectDataMapList.get(0), organizationIdMap)) {
                    return false;
                }
                dataMap.put(propertyCode, Lists.newArrayList(parseSelectValue(selectDataMapList.get(0))));
                return true;
            case STAFF_MULTI_SELECTOR:
                if (selectDataMapList.stream().anyMatch(item -> !checkUser(item, organizationIdMap))) {
                    return false;
                }
                dataMap.put(propertyCode, selectDataMapList.stream().map(this::parseSelectValue).collect(Collectors.toList()));
                return true;
            case DEPARTMENT_SELECTOR:
                if (selectDataMapList.size() > 1) {
                    return false;
                }
                if (!checkDepartment(selectDataMapList.get(0), organizationIdMap)) {
                    return false;
                }
                dataMap.put(propertyCode, Lists.newArrayList(parseSelectValue(selectDataMapList.get(0))));
                return true;
            case DEPARTMENT_MULTI_SELECTOR:
                if (selectDataMapList.stream().anyMatch(item -> !checkDepartment(item, organizationIdMap))) {
                    return false;
                }
                dataMap.put(propertyCode, selectDataMapList.stream().map(this::parseSelectValue).collect(Collectors.toList()));
                return true;
            case SELECTION:
                List<SelectionValue> selectionValueList = new ArrayList<>();
                for (Map<String, Object> item : selectDataMapList) {
                    UnitType unitType = UnitType.get(Integer.parseInt(item.get("type").toString()));
                    if (UnitType.USER == unitType) {
                        if (!checkUser(item, organizationIdMap)) {
                            return false;
                        }
                        selectionValueList.add(parseSelectValue(item));
                    } else {
                        if (!checkDepartment(item, organizationIdMap)) {
                            return false;
                        }
                        selectionValueList.add(parseSelectValue(item));
                    }
                }
                dataMap.put(propertyCode, selectionValueList);
                return true;
            default:
                return false;
        }
    }

    private boolean checkUser(Map<String, Object> selectValueMap, Map<String, List<String>> organizationIdMap) {
        if (UnitType.USER.getIndex() != Integer.parseInt(selectValueMap.get("type").toString())) {
            return false;
        }
        String id = selectValueMap.get("id").toString();
        List<String> userIdList = organizationIdMap.get("userIdList");
        if (userIdList.contains(id)) {
            return true;
        }
        List<String> errorUserIdList = organizationIdMap.get("errorUserIdList");
        if (errorUserIdList.contains(id)) {
            return false;
        }
        UserModel userModel = organizationFacade.getUser(id);
        if (userModel != null && !Boolean.FALSE.equals(userModel.getEnabled())) {
            userIdList.add(id);
            return true;
        } else {
            errorUserIdList.add(id);
            return false;
        }
    }

    private boolean checkDepartment(Map<String, Object> selectValueMap, Map<String, List<String>> organizationIdMap) {
        if (UnitType.DEPARTMENT.getIndex() != Integer.parseInt(selectValueMap.get("type").toString())) {
            return false;
        }
        String id = selectValueMap.get("id").toString();
        List<String> deptIdList = organizationIdMap.get("deptIdList");
        if (deptIdList.contains(id)) {
            return true;
        }
        List<String> errorDeptIdList = organizationIdMap.get("errorDeptIdList");
        if (errorDeptIdList.contains(id)) {
            return false;
        }
        DepartmentModel departmentModel = organizationFacade.getDepartment(id);
        if (departmentModel != null && !Boolean.FALSE.equals(departmentModel.getEnabled())) {
            deptIdList.add(id);
            return true;
        } else {
            errorDeptIdList.add(id);
            return false;
        }
    }

    private SelectionValue parseSelectValue(Map<String, Object> map) {
        SelectionValue selectionValue = new SelectionValue();
        selectionValue.setId(map.get("id").toString());
        selectionValue.setType(UnitType.get(Integer.parseInt(map.get("type").toString())));
        selectionValue.setName(map.get("name").toString());
        return selectionValue;
    }

    @Override
    public void parseRelevanceData(String relevanceInfo, String userId, List<BizPropertyModel> bizPropertyModelList, Map<String, Object> data, String publishedAttributesJson) {
        if (CollectionUtils.isEmpty(bizPropertyModelList)) {
            return;
        }

        if (StringUtils.isEmpty(relevanceInfo)) {
            return;
        }

        List<BizPropertyModel> bizPropertyModels = bizPropertyModelList.stream()
                .filter(m -> m.getPublished() && m.getPropertyType() == BizPropertyType.WORK_SHEET).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(bizPropertyModels)) {
            return;
        }
        Map<String, List<BizPropertyModel>> listMap = bizPropertyModels.stream().collect(Collectors.groupingBy(BizPropertyModel::getCode));
        Map<String, Object> map = JSONObject.parseObject(relevanceInfo, Map.class);

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            List<BizPropertyModel> propertyModels = listMap.get(entry.getKey());
            if (CollectionUtils.isEmpty(propertyModels)) {
                continue;
            }
            String relativeCode = propertyModels.get(0).getRelativeCode();
            QueryDataModel queryData = new QueryDataModel();
            queryData.setPage(0);
            queryData.setSize(1);
            queryData.setSchemaCode(relativeCode);
            if (StringUtils.isEmpty(relativeCode)) {
                continue;
            }
            queryData.setMobile(false);
            if (entry.getValue() == null) {
                continue;
            }
            queryData.setObjectIds(ImmutableList.of(entry.getValue().toString()));
            //解析表单数据项映射
            List<String> queryCodes = bizFormJsonResolveService.getRelationMappingByCode(entry.getKey(), publishedAttributesJson);
            if (CollectionUtils.isNotEmpty(queryCodes)) {
                BizObjectQueryModel.Options options = new BizObjectQueryModel.Options();
                options.setCustomDisplayColumns(queryCodes);
                options.setQueryDisplayType(QueryDisplayType.APPEND);
                queryData.setOptions(options);
            }
            Page<BizObjectModel> bizObject = this.queryBizObjectsForRelation(userId, queryData, false, true, false);
            if (bizObject == null) {
                continue;
            }
            if (CollectionUtils.isEmpty(bizObject.getContent())) {
                continue;
            }
            data.put(entry.getKey(), bizObject.getContent().get(0).getData());
        }

    }

    @Override
    public void parseQuoteDatas(String schemaCode, Map<String, Object> param) {

    }

}
